As the fintech and software development services company, we do a lot of researches and proof of concepts.
These days most real-time services like online banking, e-commerce, or social media are dependent on cloud-computing platforms. However, making those services reliable and scalable is rather challenging. Moreover, the very nature of such solutions imposes restrictions on latency and availability, all while having a direct impact on the end-user experience.
Initially, each service is intended to scale up to a particular limit, like handling ten thousand concurrent sessions. Hitting this milestone, software engineers need to re-engineer the solution to make it meet new requirements. Then history repeats itself and so on. What makes the matter worse is that financial businesses face this problem when their client base is expanding, and they succeed.
Another bottleneck resulting from business growth is associated with the data explosion. Banks and other financial organizations are obliged to keep all the information about balances, accounts, and transactions consistent and secure to be compliant with rigid regulations. Otherwise, there's a risk of losing a license, which in turn leads to significant loss of money and goodwill.
Trying to strike a balance between business requirements and technical capabilities, software engineers combine various tools, technologies, and approaches throughout the entire fintech app development process, including the division of large systems into smaller units, the use of message buses, actor model, gRPC, event sourcing, allocated storages with data projection, and others.
But what if I say that there's a more handy way to address the issues mentioned above? — Even though banking is a heavily-regulated industry, it's rather dynamic. Smaller sectors become interconnected, and Open APIs promoted by the Open Banking initiative only add more fuel to the fire. Meanwhile, the list of requirements and constraints is continuously growing, Microsoft Orleans, with its virtual actors, may be put to good use.
Let's start with defining the actor model and why it's so much sought-after for banking app development and not only that.
In simple terms, an actor-based framework is a concurrent environment where actors (primitives) can interact with each other instantly, giving single points of access for domain objects and capitalizing on a distributed lock.
Though the actor model was first mentioned in 1973 and Erlang was introduced in 1986, the authors of the latter found out about actors long after. However, this programming language, in combination with dedicated libraries for distributed processing, is still considered the most-used actor-based solution since it runs granular entities that only communicate using messaging and share no state. The similarities come from challenges that both Erlang and the actor model are actually trying to solve.
So far, the most popular actor-based framework was Akka, announced in the mid-2000s, but this Microsoft framework is quickly getting up to speed. In fact, Orleans is a cross-platform solution that combines familiar concepts (async/await, objects, interfaces, and others) and transfers them to multi-server environments, thus empowering software engineers to create scalable and robust distributed apps and cloud services.
So why MS Orleans? — Let's delve into the features that make it a good pick for banking and finance app development.
The primary difference of Orleans from Akka lies in the fact that Grains (meaning actors) in Orleans are virtual. Therefore, a fintech development team doesn't have to orchestrate a Grain's life-cycle manually, as the MS cross-platform app framework takes on this task. Besides that, obtaining a Grain reference by ID doesn't suggest that this specific Grain is actually created anywhere. Sounds great, right? Here is the scheme from the official documentation:
Image source: Microsoft Orleans documentation
In other words, a life-cycle of an Orleans Grain is given below:
Consequently, we can utilize Grains as if they are perpetually active, and MS Orleans takes on the rest.
Distributed message-passing is one of the most significant features. Typically, it's as follows:
Considering the fact that you can address objects from anywhere within the allocation unit, it makes any object absolutely transparent within the system. At this point, the implementation of intermediate communication (like REST API) is not obligated, only if it's listed in the business requirements. Consequently, it helps us to accelerate the financial services app development process and reduce costs. The outcomes may be even more tangible if we take into account the need to implement a service layer for controllers, which finally becomes more streamlined.
Natively, Grains are randomly stored on any Silo that permits the implementation. A software engineer can change this behavior with supplementary standards for each Grain separately, choosing between a load-based or local arrangement. Lastly, one can work out a custom strategy and pick a Silo based on a particular algorithm.
Reentrancy. Distributed locking
If we take a closer look at the Microsoft Orleans performance, then we should note that every method here isn’t reentrant out-of-the-box. Consequently, if some method is already handling a call, each succeeding call will wait until the prior one is terminated. Furthermore, MS Orleans allows manual configuration of the reentrancy using attributes; for example, query or read-only methods are re-enterable, while state-change patterns aren't. This lies at the core of keeping information consistent, which is so important for the banking product development process and helps to prevent various problems associated with multi-threaded account balance modification concerns, transaction replication, and more.
Distributed ACID transactions
The realization of distributed transactions is often seen as a cumbersome and tricky development issue. And considering this, the MS Orleans actor framework has something to offer. When it's well configured, your transactional entities don't have to execute rollbacks in case of failure, since this process is fully automatic. Besides that, engineering teams don't have to define transactions as ever. So how is it possible?
Start with appending special attributes to methods to employ transactions and define their behavior, including a kind of cascading:
In the next place, to sustain and modify the state of all transactional Grains, it's essential to use specific transactional state entities, all while allowing us to omit this feature in production since it comprises some restrictions and uncovered use cases.
Despite the fact that Grains are mainly regarded as field objects, there're still Grains that aren't.
Reminder and Timer
Both services handle repeatable procedures, but the goals of each vary.
If we're talking about retail banking product development, then reminders are more tangible as they assist with scheduling ETL procedures, intermittent transactions (bond payments, recurring service payments, deposit interests, and more), daily post-processing, and many other activities that should be performed repeatedly.
Microsoft Orleans is a powerful tech tool that comes with a myriad of features to solve different types of problems, even the most complex ones. The list of 'manageable' issues includes the ones that most software engineers and our teams as well, encounter during the banking product development process, including but not limited to ensuring distributed locking and single point of access to domain entities.
The programmatic model and features like the distributed messaging and co-hosting make this solution handy to work with. Though like any other technology, it has certain constraints that should be covered by developers carefully, the benefits still far outweigh, which makes it one of the best cross-platform app development frameworks for the financial services industry.