Stop thinking about databases and infrastructure

I’ve been playing with Microsoft’s Service Fabric the last couple of days and getting the gist of it. If you’ve never heard of it, that’s ok. I’m about to tell you all about it.

Service Fabric reminds me of Docker + CQRS … I suppose you could even run it in Docker if you wanted to. The next iteration will supposedly run in linux and windows and play well with Docker. In the current implementation (March, 2016), it only runs in Windows.

So, what is it? It’s basically managed microservices. In fact, it is so incredibly simple to reason about and write code for that I haven’t quite believed that it is real yet.

Also, I’m sorry this is so hard to explain. It’s so simple that I’m not sure I can adequately explain it. So, let me show you a simple rewrite of the data persistence part of my bill payment software:


        [DataContract]
        internal sealed class ActorState
        {
            [DataMember]
            public Dictionary<DateTime, decimal> Balance { get; set; }

            [DataMember]
            public Dictionary<DateTime, decimal> AvailableCredit { get; set; }

            [DataMember]
            public Dictionary<DateTime, decimal> CreditLimit { get; set; }

            [DataMember]
            public Dictionary<DateTime, decimal> Savings { get; set; }

            [DataMember]
            public List Income { get; set; }

            [DataMember]
            public List Bills { get; set; }

            [DataContract]
            internal sealed class BillObject
            {
                [DataMember]
                public Guid Id { get; set; }
                [DataMember]
                public string DiscoverType { get; set; }
                [DataMember]
                public decimal Amount { get; set; }
                [DataMember]
                public string To { get; set; }
                [DataMember]
                public DateTime DateDiscovered { get; set; }
                [DataMember]
                public DateTime DateEffective { get; set; }
                [DataMember]
                public DateTime Due { get; set; }
                [DataMember]
                public List Payments { get; set; }
                [DataMember]
                public bool MarkedResolved { get; set; }

                [DataContract]
                internal sealed class PaymentObject
                {
                    [DataMember]
                    public DateTime PaymentIssued { get; set; }
                    [DataMember]
                    public DateTime PaymentCompleted { get; set; }
                    [DataMember]
                    public decimal Amount { get; set; }
                    [DataMember]
                    public string Tender { get; set; }
                }
            }

            [DataContract]
            internal sealed class IncomeObject
            {
                [DataMember]
                public string PaymentFor { get; set; }

                [DataMember]
                public decimal Amount { get; set; }

                [DataMember]
                public DateTime NextEvent { get; set; }

                [DataMember]
                public DateTime Start { get; set; }

                [DataMember]
                public Guid Id { get; set; }
            }

            public override string ToString()
            {
                return string.Format(CultureInfo.InvariantCulture, "HouseHold.ActorState");
            }
        }

That is the serializable data structure that contains everything the application needs to know about the financial state of affairs. Normally, we’d have to read that in from a database, and somehow write it back. We’d also have to worry about migrating the schema and dealing with nulls in the data, now we just have to follow these relatively simple guidelines.

Or, if you’re like me and were using CQRS + ES, you don’t need it anymore. You still want to keep your idempotency and you might want to keep around some projections for reporting … but mostly, you just need to delete a bunch of code.

With Service Fabric, we get persistent data based on the actual data, in the actual form, when we need it. Even easier to wrap your head around, is the fact that each instance of an Actor is single threaded. This can easily lead to a prevention of all kinds of fun and interesting bugs you may find in the wild.

The biggest downside is the messaging subsystem. It’s guaranteed to fire off a message at least once, so you may see the same thing happen several times … idempotency is especially important when designing the application. So far, in converting my bill payment software to this framework, I’ve had fun deleting code. So much code was harmed in the production of this blog post.

You get fault tolerance for free, replicated persistence, and a myriad of other “nice to haves” that you usually don’t have time to build when rolling your own. This stuff is magic, and I’m quite surprised the community hasn’t found it and tried to build in other languages.

Ah well, I guess I’ll sit back and wait for it to become generally available before I get too excited.