DevConf 2017

The first, 2017 edition of DevConf has ended. Both, on the social level and the content level it rocked. Also, this was the very first time I’ve ever given a presentation in English.

Top 3 talks

I haven’t seen all of the talks as I was preparing for mine. Frankly speaking, it’s quite hard to both enjoy a talk and be stressed before yours so I chose a third option and drank a few cups of delicious coffee (no stress, no attendance, just coffee). If I had to choose top 3 talks (in no particular order) these would be:

What is .NET Standard? by Adam Ralph

An interesting presentation showing the mess before .NET Standard and the beauty of the common interface to bind all the platforms together. Good jokes about graphs, some numbers and, the last but not least, insightful journeys into type-forwarding that enabled this whole thing to work.

Kudos to Adam.

Domain Driven Design: The Good Parts by Jimmy Bogard

A very interesting presentation of removing bad parts from DDD, making it focused on things that matter the most, which is…. (you better watch the presentation). It’s worth to add that it was beautifully and naturally storyfied with real projects Jimmy was involved in.

Kudos to Jimmy.

“Cargo Cults” in Building Modern Software Systems by Sebastian Gębski

This is the presentation where some people could feel offended. Or terrified. Or both. Sebastian dissected industry standards and mechanisms showing, how rotten it is on multiple levels. It’s a really heavy topic and before this presentation I didn’t know things like “Point of View” and others. A very eye opening presentation.

Kudos to Sebastian.

 

Lockstitch, a mechanical stitch made by a sewing machine

TL;DR

This post sums up my work on SewingMachine and introduces the new project, based on Service Fabric called Lockstitch.

Whys, reasoning and more

Due to various reasons including some NDA stuff that I cannot share and after lots of thinking about the way I could push Sewing Machine further, it looks that this project won’t receive much more attention from me. Just to get it clear, this is not related to any “I don’t have time for OSS now” or “omg, nobody likes my project”. It’s simple calculations followed by a few discussions about directions where this project could head.

The nature hates vacuum and at the same time when claiming that SewingMachine is almost dead, I want to bring Lockstitch to the table. It’s again about Service Fabric, it’s again about performance, it’s again about distributed systems done right. Only better and on a different level. Lockstitch is aiming to work with the lowest fabric component, called replicator. The overall goals, as I mentioned are the same.

If you want to see the where is it heading, a list of issues should provide you all the needed information.

It’s important to mention Tomasz Masternak, who is a co-author of Lockstitch.

Summary

Good ideas, don’t die, they reappear in a different shape. This is why Lockstitch could be treated as SewingMachine++.

Await Now or Never

Intro

This post is a continuation of implementing a custom scheduler for your orchestrations. We saw that the Delay operation is either completed or results in a never ending task, that nobody ever completes. Could we make it easier and provide a better way for delaying operation?

Complete or not, here I come

The completed Delay operation was realized by


Task.CompletedTask

This is a static readonly instance of a task that is already completed. If you need to return a completed task, because the operation of your asynchronous method was done synchronously, this is the best way you can do it.

For cases where we don’t want continuations to be run, we used:


new TaskCompletionSource<object>().Task

which of course allocates both, the TaskCompletionSource instance and the underlying Task object. It’s not that much, but maybe, as there are only two states of the continuation: now or never, we could provide a smaller tool for this, that does not allocate.

Now OR Never

You probably know, that you might create your custom awaitable objects, that you don’t need to await on Tasks only. Let’s take a look at the following class


public sealed class NowOrNever : ICriticalNotifyCompletion
{
  public static readonly NowOrNever Never = new NowOrNever(false);
  public static readonly NowOrNever Now = new NowOrNever(true);

  NowOrNever(bool isCompleted)
  {
    IsCompleted = isCompleted;
  }

  public NowOrNever GetAwaiter()
  {
    return this;
  }

  public void GetResult() { }

  public bool IsCompleted { get; }

  public void OnCompleted(Action continuation) { }

  public void UnsafeOnCompleted(Action continuation) { }
}

This class is awaitable, as it provides three elements:

  1. IsCompleted – for checking whether it was finished (fast enough or synchronously to do not build whole machinery for an asynchronous dispatch)
  2. GetAwaiter – to obtain the awaiter that is used to create the asynchronous flow
  3. GetResult

Knowing what are these parts for, let’s take a look at different values provided by NowOrNever static fields

NowOrNever IsCompleted OnCompleted/ UnsafeOnCompleted
Now true no action
Never false no action

 

As you can see, the completion is never called at all. For the Never case, that’s what we meant. What about Now? Just take a look above. Whenever IsCompleted is true, no continuations are attached, and the code is executed synchronously. We don’t need to preserve continuations as there are none.

Summary

Writing a custom awaitable class is not a day-to-day activity. Sometimes there are cases where this could have its limited benefit. In this NowOrNever case, this allowed to skip the allocation of a single task, although, yes, the created async state machine takes probably much more that a single task instance.

Implementing a scheduler for your orchestrations

TL;DR

We’ve already seen here and here that with async-await one could easily sketch an orchestration/saga for any process that should be both, robust and resilient. It’s time to take a look how a scheduler for such a process could be implemented.

Delay with no Task

Usually, when we want to delay an action in an asynchronous flow, we use Task.Delay. This method schedules a continuation with the rest of our code, to be executed after the specified delay. The usage is as simple as:


await Task.Delay(TimeSpan.FromSeconds(1.5));

This is fine, when we want to postpone an action for a few seconds, but what in case of processes that want to be frozen for days? How could you implement it?

First, let us rephrase the delay to a method that is provided by the base orchestration class (you can always have a base, can’t you?).


await this.Delay(TimeSpan.FromSeconds(1.5));

With this assumption, we can move forward and take a look at a possible Delay implementation.

Delay for Orchestrations

The whole idea of this orchestration is based on snapshoting its changes as events and make them replayable. In other words, if a failure occurs, the orchestration process should be resurrected on another node with no changes in the flow. This makes implementation a bit trickier, but is needed for providing strong foundations for our processes. Let’s take a look at Delay possible implementation.


protected Task Delay(TimeSpan delay)
{
  var date = GetDateTimeUtcNow();
  var scheduleAt = date + delay;

  ScheduledAt existingDelay;
  if (TryPop(out existingDelay))
  {
    if (existingDelay.Value > context.DateTimeUtcNow())
    {
      EndCurrentExecution();
      return new TaskCompletionSource<object>().Task;
    }

    return Task.CompletedTask;
  }

  if (scheduleAt <= date)
  {
    return Task.CompletedTask;
  }

  Append(new ScheduledAt(scheduleAt));
  EndCurrentExecution();
  return new TaskCompletionSource<object>().Task;
}

The first line of this methods calls to GetDateTimeUtcNow. As you can imagine, this gets the UTC current date. It has one additional property though. Do you remember that we need to make this method possible to be executed multiple times with the same effect? This means, that the result of GetDateTimeUtcNow will be recorded and when we, for any reason like the process kill, enter the orchestration again, it will provide the same value. Effectively, it will be now from the first execution of it.

The next step is to calculate the date when the delay should end, where the next execution is ScheduledAt.

We TryPop a prerecorded event. If the orchestration was already active, it left a trace, an event in the history, that we can pop. If there’s an entry, we compare it with the current UtcDateTimeNow. If the orchestrations should wait more we just mark it as one that requires ending execution. Next we return  new TaskCompletionSource<object>().Task
which effectively is a never ending task. This means that any continuation attached by the caller of this method, either explicit or implicit using await won’t be run!

If there was no event and the date that Delay is scheduled for some reason lower then current date, a completed task is returned. Otherwise, an event is added and the current execution is ended with the same pattern: by setting a notification about execution not proceeding any longer and returning a never completing task.

Execution status

The caller responsibility is to gather information whether the orchestration ended or was scheduled for later execution. This is done by awaiting one of the tasks. Either the task of the orchestration itself or a task that is EndCurrentExecution sets the result.


await Task.WhenAny(
orchestration.Execute(),
currentExecutionEndingTask);

Summary

We saw how powerful can be asynchronous flows, especially when connected with optional calling of scheduled continuations. With a simple recording of events we were able to create an orchestration tooling that is easy to use by the end user (programmer), but still provides an interesting and powerful semantics of a time dependent process.

Top Domain Model: the end

TL;DR

This is the end of mini series related to Top Domain Model. Let’s quickly go through all the topics we’ve covered.

Top Domain Models

  1. In I’m temporal we’ve covered one of the most underused techniques in modelling. Adding an explicit temporal dimension to the model.
  2. Reading that I’ve been pivoting all night long brings a lot of different questions about aggregates and modelling them from different perspective, selecting the most useful.
  3. In behaviors, processes and reactions we observed that aggregates on their own are meaningless. Why one would capture all the events if none of them caused a reaction?
  4. The last chapter reminds to not be so implicit and that capturing the same value twice or more sometimes is required to build a meaningful and useful model.

Summary

I hope you enjoyed these loosely connected articles about modelling. As always, it’s not about the most real models, but the most useful ones.

Orchestrating processes for fun and profit

TL;DR

I’ve already shown here that with some trickery you can write orchestrations in C# based on async-await. It’s time to revisit this idea, now with a custom orchestration of mine.

Show me the code!

The orchestration is based on the event sourcing infrastructure built by me. This project is not public (yet) but it’s similar to any other ES library. The main idea behind building an orchestration on top of it is that state changes of an orchestration are easily captured as events like: GuidGenerated, CallRecorded, UtcDateTimeObtained, etc etc. If this is the case, we could model any orchestration as an event-sourced aggregate.

Here it is an example of reserving a trip, that needs to coordinate between reserving a hotel and a flight. Additionally a few calls were added to just show what the orchestration is capable of

orchestration.png

  • Line 19: orchestration can delay it’s execution. It does not mean that it will stay in memory for that long. It will record the need of delay to be woken up when the time comes
  • Line 22: when a Guid is generated with Orchestration.NewGuid it means that it will have the same value when the orchestration is executed again. Process dies and the orchestration is executed elsewhere? Don’t you worry, the guid value has been recorded
  • Line 25: same with dates
  • Line 28: an external call to any system. Here, we try to ReserveHotel. 3 attempts are made with a exponential back off. Between calls, if the configured timespan is long enough, saga can be swapped from memory (like with Delay)
  • Line 33: same as with hotel
  • Line 38: the compensation part

Execute it!

The execution would take the persisted events and replay them if process failed, machine died, etc. on another host. Because before every external call, all the recorded events are persisted, it ensures that even during a rerun, all the values will be exactly the same and calls that were already made won’t be made again.

Summary

Orchestrating with async-await trickery is much easier and can be written in a dense, simple way of a regular method call. Having an event-sourced foundation makes it even easier as you can use already existing pieces and persist all orchestration events as event of some kind of aggregate.

Top Domain Model: Don’t be so implicit

TL;DR

Make things implicit (more) explicit. This is the mantra we often hear, but when touching the reality of software development, often forget, because of the magic beauty of technology, tooling, etc. Should we repeat this, when modelling domains as well?

Auditing

It doesn’t matter whether you apply DDD or CRUDdy. It’s quite often to hear that a system should provide a some kind of audit. Then we provide a table like History or Audit, where all the “needed” data are stored. What would be the columns of this table? Probably things like:

  • user
  • operation
  • field changed
  • value entered

or something similar. Again, depending on the approach these data could flow through the system as some kind of tuple, before hitting the storage.

When dealing with a business process that uses an accountant id, just for registering who’s responsible for tax calculations, would you “reuse” the user from a tuple above, or would you rather create a variable/field that is named accountantId, even if the values in accountantId and user would be the same? What would be your choice?

Event sourcing

ProperyChanged, is one of the worst events ever. Yes, it’s so beautifully generic and so well describing the idea of event sourcing, grasping changes in the model. It can be gathered implicitly, just by comparing an object before and after applying an action. At the same time it’s so useless, as it provides no domain insight and could be blindly used in any case. This approach is often referred to as property sourcing and is simply wrong.

The power of event sourcing, or modelling events at all, is grasping real business deltas of the domain. No playing mambo-jumbo with the tooling and implementing the new minimal change finder. Being explicit is the key to win this, to design a better model.

Summary

There are many more examples of explicit vs implicit and abusing modelling by playing not with the domain but with the tooling. When modelling, analyzing, ask yourself these questions. Should I really reuse it? Should I really make it generic? Quite often the answer will be no, and trying to do this, might hurt your model, and effectively, you.