Thursday, 4 June 2015

Learning Java through Android

Introduction

I often get the hankering to toy with a language other than C#. It's always interesting to see what other languages do differently, think about why, and possibly even carry those concepts back to .NET.

Java is a big portion of the industry and also a language I didn't know much about, so I got a hold of the Android development tools and had a bit of a hack.

Here are my initial thoughts!

Android != Java

Though Android code is written in Java, it's an older version of Java, so you miss out on these cool Java 8 features that are actually pretty familiar to a C# developer.

Additionally, most of the code you write for Android is leveraging the Android framework - which is unsurprising given the context - but means that there's limited knowledge that can be transferred to Java development in general.

Java != C#

With all the comparisons drawn between C# and Java, you could be forgiven for thinking you'll be able to hit the ground running with no prior knowledge of Java.

It's fairer to say that you'll hit the ground, stumble a bit, then be up to running speed quicker than you think.

Java is Less Militant

There's an air of flexibility in Java development that doesn't exist in C# which can trip you up if you're not careful.

Overridden methods are a great example. In Java, a method being able to be overridden is opt out, whereas in C# it's opt in - an important distinction.

Here's an override in C#:

public class BaseClass 
{
    // *virtual* says this method can be overridden
    // (opt in)
    public virtual void DoStuff()
    {
    }

    // lack of *virtual* says this method can't be overridden
    public void DoOtherStuff()
    {
    }
}

public class DerivedClass : BaseClass
{
    // If we miss the override keyword, the compiler complains
    // that we need either *override* or *new* to explicitly
    // define our expected behaviour for this method
    public override void DoStuff() 
    { 
        base.DoStuff();
    }
}    

And here's an override in Java:

public class BaseClass 
{
    // lack of *final* says this method can be overridden
    public void DoStuff() 
    { 
    }

    // *final* says this method can't be overridden
    // (opt out)
    public final void DoOtherStuff() 
    { 
    }    
}

public class DerivedClass extends BaseClass
{
    // This override annotation is completely optional.
    // If we don't include it, the method still gets overridden!
    // If we do include it, the compiler will check that there's a
    // method to override.
    @Override
    public void DoStuff() 
    { 
        super.DoStuff();
    }
}    

Conclusion

It may not have all of the wonderful features of C# right now (e.g. async/await), but in its flexibility, Java brings its own flavour to the table and is a fantastic language in its own right.

I personally prefer a strict development environment, but you only have to take a quick look at a Python forum to know that not everybody feels the same way.

Whichever way you lean, I recommend that you give Java a fair chance, it's a great change of pace and good fun too!

Sunday, 19 April 2015

async/await: An Unexpected Journey

Introduction

I recently ran into an issue when using async/await with SqlBulkCopy's WriteToServerAsync method and a bespoke implementation of IDataReader, the root cause of which was so surprising that I just had to post about it!

The Problem

The basic process was implemented as follows:

  • Set the current thread's culture to Spanish (es-ES)
  • Await (configured to preserve the culture) a SqlBulkCopy.WriteToServerAsync call with a custom reader
  • Custom reader uses the current thread's culture to decide which resources to use

Expected behaviour:

Due to how async/await and ConfigureAwait preserve the Synchronization Context, it was expected that the custom reader would find the current thread's culture to be Spanish and locate the appropriate Spanish resource files accordingly.

Actual behaviour:

The reader found the current thread's culture to be Spanish, but only sometimes. At varying intervals during a single awaited call to SqlBulkCopy's WriteToServerAsync, the thread on which the reader's Read was executed forgot the culture, reverting to english!

The Investigation

It didn't take too long to identify that the issue was occurring within SqlBulkCopy's WriteToServerAsync method and wasn't anything I had invoked myself, so I popped open the reference source for SqlBulkCopy and through some digging I found this:

private Task WriteRowSourceToServerAsync(
                int columnCount, 
                CancellationToken ctoken) 
{
    Task reconnectTask = _connection._currentReconnectionTask;
    if (reconnectTask != null && !reconnectTask.IsCompleted) 
    {
        if (this._isAsyncBulkCopy)
        {
            TaskCompletionSource<object> tcs = 
                        new TaskCompletionSource<object>();

            reconnectTask.ContinueWith((t) =>
            {
                Task writeTask = WriteRowSourceToServerAsync(
                                    columnCount, 
                                    ctoken);

                if (writeTask == null) 
                {
                    tcs.SetResult(null);
                }
                else 
                {
                    AsyncHelper.ContinueTask(
                                    writeTask, 
                                    tcs, 
                                    () => tcs.SetResult(null));
                }
            }, ctoken); 

            return tcs.Task;
        }
        else 
        {
            // Trimmed for brevity, check the reference source
            // for the full method if interested.

Looking at this code, the question immediately became:

Is async/await's SynchronizationContext implicitly
preserved by TPL's ContinueWith?

The Answer

Evidently, the answer is no, TPL's ContinueWith does not implicitly preserve async/await's SynchronizationContext.

Where async/await uses SynchronizationContext, TPL uses TaskScheduler. The only way to preserve the SynchronizationContext with ContinueWith is to pass a TaskScheduler copied from the current SynchronizationContext when calling it:

await Task.Delay(TimeSpan.FromSeconds(1))
          .ContinueWith(
              (t) => 
              { 
                  // whatever you like 
              },
              // Handy helper method!
              TaskScheduler.FromCurrentSynchronizationContext());
} 

Seeing as I don't own the code in which the call to ContinueWith is being made, adding the call to TaskScheduler.FromCurrentSynchronizationContext isn't really an option.

The quick fix here was to simply restore the current thread's culture to Spanish at the start of the custom reader's Read method before proceeding. (This isn't so much a fix as it is a workaround, but it achieves the desired result with minimum impact. Sometimes doing it cleanly is better than doing it "right".)

Final Thoughts

The take away from this is to remember that just because a method returns an awaitable Task doesn't necessarily mean that the Task being returned uses async/await in its implementation, it could well be using TPL and ContinueWith, in which case your SynchronizationContext won't be preserved.

If you run into an issue where async/await and an asynchronous method you didn't write aren't behaving consistently as expected, be sure to check the reference source for how the asynchronous method is implemented and proceed accordingly.

Monday, 13 April 2015

Event Handlers and C# 6's Null-Propagating Operator

I've previously waxed lyrical about the incredibly cool null-propagating operator coming in C# 6.0, but Jon Skeet recently raised an excellent point regarding event handlers.

_______________

Since the null-propagating operator can be used with method calls, what once had to be written as:

if (eventHandler != null)
    eventHandler(this, args);

Will soon be able to be written as:

eventHandler?.Invoke(this, args);

I think we can all agree that the latter is cleaner!

If you'd like to know more, then be sure to read the full post on Jon Skeet's blog and follow him if you aren't already, as he always goes into incredibly well considered depth on a topic!

Friday, 13 February 2015

Liquid for C#: Defining Success

Introduction

In the High-Level Overview for this series I mentioned that I'll need a way to measure the success of this project as it progresses.

As this project's aim is to create a one for one replica of the Ruby implementation of Liquid's behaviour, I will be porting Liquid's integration tests to C# and following a test driven approach.

What's in a Name?

Though they have been called integration tests in Liquid's code, the majority of these tests are in fact functional acceptance tests, which is what makes them useful for confirming that the behaviour of the system is correct.

Unit Test

Tests the behaviour of a single system component in a controlled environment.

Integration Test

Tests the behaviour of major components of a system working together.

Functional Acceptance Test

Tests that the system, per the technical specification, produces the expected output for each given input.

Unit and integration tests verify that the code you've written is doing what it was written to do, while functional acceptance tests verify that the system as a whole, without consideration for the structure of its internal components, does what it is designed to do.

Any Port in a Storm

There are hundreds of tests to port to C# and, as it turns out, not all of the tests in the Ruby implementation's integration namespace are integration or functional acceptance tests... some are unit tests!

The porting process is therefore a matter of replicating the original tests as faithfully as possible, translating them into functional acceptance tests where needed.

A test that ported smoothly

# Ruby
def test_for_with_range
    assert_template_result(
        ' 1  2  3 ',
        '{%for item in (1..3) %} {{item}} {%endfor%}')
end
// C#
public void TestForWithRange()
{
    AssertTemplateResult(
        " 1  2  3 ", 
        "{%for item in (1..3) %} {{item}} {%endfor%}");
}

A test that needed translation

# Ruby - The below are unit tests
#        for methods escape and h
def test_escape
    assert_equal '<strong>', @filters.escape('<strong>')
    assert_equal '<strong>', @filters.h('<strong>')
end
// C# - Rewritten as a test of the 
//      output expected from a template
public void TestEscape()
{
    AssertTemplateResult(
        "&lt;strong&gt;", 
        "{{ '<strong>' | escape }}");
}

When translating from a unit or integration test to a functional acceptance test, I'm using the documentation and wiki as the design specification. This ensures that the tested behaviour is the templating language's expected behaviour, not just the behaviour I expect!

What's Next?

Once all of the tests are ported, the next step will be to start writing the code to pass those tests. Remember, in Test Driven Development we start with failing tests and then write the code to make those tests pass.

The AssertTemplateResult method mentioned earlier currently looks like this:

protected void AssertTemplateResult(
                   string expected, 
                   string source)
{
    // TODO: implement me!
    throw new NotImplementedException();
}

There's still a few hundred more tests to port yet, though, so wish me luck!

Monday, 9 February 2015

Liquid for C#: High-Level Overview

Introduction

In the Liquid For C# series, I will be writing a C# interpretor for the Liquid templating language from scratch.

In this first post I define the project's scope and overall intention. Code does not factor into this stage at all, it's purely about the API's purpose, not it's implementation.

Broad Strokes

The first step in any project is to define what it will be doing at the highest level. Ideally, this should be expressible as a single sentence or a simple diagram.

This project's definition is deceptively simple: Template + Data = Output.

Armed with this very general definition, the next step is to break the overall process into broad, functionally cohesive chunks. I find that this is best achieved by running through potential use cases. The below is the outcome of that process.

It immediately jumps out at me that the Abstract Syntax Tree and steps that follow are implementation agnostic. This means that they are not specific to Liquid and, because of this, can be re-used in any templating language interpretor.

Defining Success

The question then becomes one of how to know when the project fulfils its purpose.

As the aim of this project is to provide a full C# implementation of Liquid's behaviour as it is currently implemented in Ruby, I will port all of the integration tests for Liquid to C# and follow a Test Driven Development approach. I will only consider the project to be a success when it passes all of the original tests.

What Next?

In bigger teams or projects its necessary to delve much deeper in the design phase, going as far as to define the interfaces for the API and how they plug together so that all involved parties can work independently without going off in completely different directions.

Since this is just me working on a hobby project, though, I'll instead be taking a very iterative approach and in the next post I'll be writing code!

Wednesday, 4 February 2015

Restructuring DotLiquid: Part 3

The Issue at Hand

For those who didn't know, DotLiquid is a straight C# port of Liquid, a library written in Ruby.

The Ruby programming language is significantly different to C#, so even best-effort attempts at like-for-like reconstruction of the library inevitably lead to structural issues in the API's design.

Lost in Translation

The structural issues that come from direct porting include:

  • Excessive use of static classes.
  • Excessive use of Reflection.
  • Lack of Object Oriented design, leading to inflexibility.
  • Duplicate code. Tight knit classes force code to be repeated.
  • Excessive boxing and unboxing, leading to degraded performance.

That's not to do down DotLiquid though, which is an exceptional direct port of the original library, as for the majority of cases it is more than fast enough and anyone who has written code using the Ruby implementation of Liquid will be able to pick up DotLiquid and use it in the exact same way without hesitation.

In my quest to produce the perfect API, however, my implementation has become so far removed from DotLiquid's interface, implementation and intent that I have decided to start afresh.

Be sure to come back for my next post, where I'll begin the high level design process for the API including how and why I'll be drawing distinct boundaries between its elements.

Friday, 23 January 2015

Restructuring DotLiquid: Part 2

Bringing down the Hammer

I mentioned in Part 1 that DotLiquid's Condition hierarchy could do with being a bit more object oriented.

As conditions are a relatively small and isolated part of the API, it's a great place to start this series in earnest, so that's where I'll begin.

The Restructure

Here's a before and after of the Condition class hierarchy.

BEFORE

AFTER

First, I introduced a new interface, ICondition, and I did this for two reasons:

  1. Not all future developers will want to use the class ConditionBase as a base - they might have new code requirements or their own base class.
  2. No class that has a dependency on conditions should be forced to depend upon a specific implementation - by using the interface I make those classes compatible with any implementation.

Next, I refactored And and Or logic out of Expression and into their own classes. I did this because the code for And, Or and Expression may be logically cohesive, but it is not functionally cohesive. Incidentally, their code's lack of functional cohesion is what made them so easy to separate.

I made ConditionBase an abstract class to better indicate its purpose as a foundation, as opposed to a class that can be used effectively on its own.

I moved the static collection Operators out of ExpressionCondition and into its own class. This needs further work, as it shouldn't be static at all, but it's a start. More on this in a later post.

The IsElse property is a classic code smell because it will only be true on one occasion: when the Type is ElseCondition. Any logic that utilises the property would be better off inside the ElseCondition itself, thereby encapsulating the functionality, so I changed the signature of the Evaluate method to take a ConditionalStatementState object and moved the check for whether an ElseCondition should render inside ElseCondition.

// BEFORE
// =====================
// The owning block's render method:
var executeElseBlock = true;
foreach (var block in Blocks)
{
    if (block.IsElse)
    {
        if (executeElseBlock)
        {
           return RenderAll(block.Attachment, context, result);
        }
    }
    else if (block.Evaluate(context))
    {
        RenderAll(block.Attachment, context, result);
        executeElseBlock = false;
    }
}

// The ElseCondition's evaluate method:
public override bool Evaluate(Context context)
{
    return true;
}

// AFTER
// =====================
// The owning block's render method:
var state = new ConditionalStatementState(context);
foreach (var block in Blocks)
{
    if (block.Evaluate(state))
    {
        ++state.BlockRenderCount;
        var retCode = block.Render(context, result);
        if (retCode != ReturnCode.Return)
            return retCode;
    }
}

// The ElseCondition's evaluate method:
public override bool Evaluate(ConditionalStatementState state)
{
    return state.BlockRenderCount <= 0;
}

It's worth noting that I could have introduced an additional base class for AndCondition and OrCondition for which they override the evaluate method and share the Left and Right properties, but they do so little internally that it felt like overkill. Should they ever grow in size, an abstract base class can be retrofitted painlessly enough.

Summary

Overall, this is a great first step on the path to a clean and pure API, but there's still a lot more work to be done. I suspect that by the end of this series DotLiquid's API will be a significantly different beast, exposing the same functionality in a much more flexible API.

I'm really enjoying the challenge and, if you'd like me to clarify anything, feel free to let me know in the comments!