Before we start talking about application’s architecture with dinemic framework, let’s take a short look on common, very popular application architecture
System architecture
Standard application architecture
Usually your application (web, standalone, android) has following parts:
- Database – stores data globally, for whole application
- Controller + View – displays and controls access to the data in user friendly form (UI) or in computer friendly form (API)
- Optional: load balancers, storage for large files and so on…
Sometimes, when you want to improve performance, you need to add load balancer, some configuration files and other stuff, that makes your application failure proof. Finally architecture of such application might look like this:
In large, corporate applications it is very common to integrate also identity services, split responsibilities for different services and many more, which makes final application very compels.
When it comes to hardware failure and split brains, detached part of cluster might stop working and will be not synchronized with rest of cluster. In applications that are something more than software (IoT, communication, etc.) this might cause that hardware is also in different state than database shows. To prevent such failures, expensive hardware is necessary to buy to support cluster sustainability.
Finally, HA architecture with redundant component might look like:
Dinemic architecture
With dinemic framework you can get scalability and decentralization for free. Dinemic framework is kind of ORM for key-value database. Each node has its own copy of database synchronized with other nodes.
Synchronization is done after every change in any object in database, so you can recreate any object from scratch in any point of cluster to start your application there. Security is provided by cryptographic keys, assigned to each particular object registered in framework, transparently for the user and developer.
Also very detailed resource management is given without any additional effort to developer. And, what is important, this is based not on database permission table, but on cryptography. In dinemic, granting or revoking permissions, securing data and group permission management for any object causes cryptographic modification of encryption keys for interested objects. That leverages security to next level.
Any kind of split brain will no longer cause your cluster failure. Once cluster is divided, two its parts works on last known set of data. On re-join all modifications are applied with respect to blockchain-like data synchronization mechanism, also based on cryptographic tools.
Application architecture
The dinemic framework enforces using event driven and data driven software architecture with its ORM, which provides above advantages. Before you start writting your first application, you should have following rules in your head:
You are not changing data. You only accept or reject changes
Usually API request for remote service triggers change of data in database. In Dinemic the framework is changing data consistently. Your role is only to filter unauthorized or wrong changes on your local copy of database.
Due to readines to be launched on decentralized environment, with possible split brains, dinemic applications have own copy of all data on local nodes. This might lead to inconsistency on different nodes, but with applying following rules it should be acceptable.
You should store data in DModel and DField/DLists
Otherwise it won’t be synchronized by Dinemic. This is how this framework works. Only data stored in DModel and DLists inside DModel class will be considered to perform synchronization across whole cluster. This is described in next chapters of documentation.
Any change in database could trigger your model
Probably you’ve used to implement following flow:
- API Request
- Check in DB if we can handle that
- Handle that
- Update database
In dinemic framework things are a bit different. First, you should create your data model to represent physical resources as close as possible. Second, you should be aware that one logic will be executed on all nodes on the same database change. Probably only one node will be able to handle that change properly. To handle database change properly you should create listener, which will accept or reject such change. In such listener:
- Before update (on_update listener): Is database change signed by authorized key? If not, reject. We don’t want to have a mess
- Before update (on_update listener): If we need to do something before change was made, do it here. You can limit it only to node, which owns the resource
- Change is applied to database by Dinemic Framework
- After update (on_updated listener): perform any actions necessary after database was changed.
Above shows that any change could be rejected in the same way as in API-oriented application. What’s more, such listener could be applied to any model, specific model or just single field of your model. So you could select precisely if your database model will be changed and where.
Example: It could look like a mess for a first time, but finally you will get logics much closer to communication known from human channels, like email:
- Does somebody trusted wants action from me? If not trusted, ignore it
- Does this action apply to me or I was only CC’ed?
- Acknowledge that something was decided
- Do any post-email actions
Finally, with dinemic you could apply following action listeners to make application flow secure:
- Apply predefined listener – reject all unauthorized actions on all fields in all models (*)
- Apply your listener on your model or field to check resource availability (i.e. do we still have this item in magazine?)
- Apply listener related to the action
Unauthorized changes
Sometimes we need to accept actions made by unauthorized objects. For example getting order in our store (model Store) by unauthorized user (model User).
First option is to model logics as following: User needs to put new order details into Store’s internal list of orders. Then we could add as first listener following logics:
- catch such action first (i.e. placement of new order in our shop)
- will reject on any node that does not own this resource
- make the same change, as authorized object (new update)
- finally reject unauthorized, original change
- new change will be accepted by everybody
Second option, much better is to enforce User to create new object of model Order with state field and authorized Store’s public key. Then both, User and Store will be able to modify state of such order. However listeners applied by Store (where store is physically located) should prevent changes done by User when state is individually changed from “placed” to “accepted”. Such change should be accepted only as done and signed by store.
Comparison
Common architecture | Dinemic app architecture | |
---|---|---|
Failure proof | Low or medium with expensive hardware and complex configuration | Very high, no single point of failure, trivial node replacement |
Split-brain proof | Low, any split brain might corrupt data or other hardware state | VEry high, internal mechanisms and application architecture prevents damages during split brain and after rejoin |
Backup | Necessary external tools, sometimes very expensive | Each cluster node has full copy of data with history in form of block-chain |
Scalability | Complex, usually very expensive | Guaranteed by framework |
Security | Requires additional effort, usually expensive | Guaranteed by underlying framework, managed by cryptography |
Performance | Might be high after implementing right, usually expensive solutions | Medium, depends on hardware and networking performance. With proper configuration of cluster domains might be very high |