FROM: 5HT
TO: #BPE
DATE: 3 MAR 2015

E-Banking Application

Overview

Our aim was to provide web-banking app to serve customers' deposit accounts with the best possible functionality/codesize rate. We've created fast and robust responsive web application that can fit any devices and provides modern secure features over the fast WebSocket channel.

Minimal

When we are talking about enterprise solutions we always talk about giants, like CLR/JVM virtual machines and SAP/Oracle warehouses. However systems needn't to be complex and technologies like K langauge and Erlang provide enough declarative expressivness for business applications. Having some experience in building banking software we provide smallest possible processing infrastructure to be easily verified and managed while being robust at the same time.

The application is built using Erlang libraries from synrc and spawnproc GitHub organizations. Consumer appliaction hosts custom rules depending protocol or server module. E.g. your business application defines a set of business processes which are driven by BPE server, this application usually called ACT, from "activity server". N2O-based web application usually called WEB or SPA. See Picture 1.

The architecture is based on spawnproc processing applications and relies on synrc Erlang stack and N2O protocol. It is run using voxoz development tools. The application can be distributed as a single file, is able to run on Windows, Linux and Mac and fits to 2.88MB diskette. For processing opening application database consumes 2K per record.

Despite small size of application, it can operate hundred of millions records in KVS database. All banking "big-data" of transaction chains can be managed withing a single diskette. That is top-key feature of spawnproc application stack.

Picture 1. Erlang/OTP applications

KVS 1029 128K REST database secondary indexes DYNAMO, FRAG Riak, Mnesia, Redis DBS 230 60K SpawnProc Intermediary Bank Schema MQS 347 32K Pub/Sub access message bus AMQP, GPROC TPS 874 108K transactional processing system RIAK CORE IBAN, EMV UPL PLAIN TEXT English Universal Processing Language N2O 4274 528K WebSocket protocol BERT JavsScript CSS single page apps nitrogen DSL WEB 3163 252K PrivatBank Deposit Application SERVICES 3079 496K PrivatBank Service Bridge BPE 591 68K BPMN 2.0 protocol XML/DSL process management FORMS 1626 188K SpawnProc Intermediary Bank Form Set ACT 1417 176K PrivatBank Deposit Processes

Responsive

Our aim was to provide smallest possible minimalistic application for PrivatBank customers, who are using deposit accounts. We've created fast and robust responsive web application that can fit any devices and provides modern secure features over the fast WebSocket channel.

Fact: SSL page load is about 380ms from AWS ELB. The uncompressed size of SPA static assests is also hyperoptmized:

$ cloc js css htm
Language         files   blank    comment   code
------------------------------------------------
Erlang           69      605      169       4800
HTML             4       60       23        394
Javascript       9       246      123       1884
CSS              1       32       11        176


Picture 1. Responsiveness across Mobiles, Pads and Desktops

Performant

Fact: size is 2.1MB and boot time is 2s

$ ls -lh deposits
-rwxr--r--   1 5HT  staff   2.1M Feb 21 04:07 deposits
$ date && ./deposits
Sun Mar  1 01:53:42 EET 2015
Eshell V6.2  (abort with ^G)
1>
=INFO REPORT==== 1-Mar-2015::01:53:44 ===
deposits_sup:Deposits WebSocket Server is started.


Fact: It is easy to hold 20Mbps to the small AWS instance.

$ tcpkali -T10s -r 10000 -c 50 --first-message "N2O," \
          -m PING --ws deposits.privat.bank/ws/static/app/open.htm
Ramped up to 50 connections.
Total data sent:     20.4 MiB (21390904 bytes)
Total data received: 3.4 MiB (3602222 bytes)
Bandwidth per channel: 0.399 Mbps, 49.9 kBps
Aggregate bandwidth: 2.878↓, 17.093↑ Mbps
Test duration: 10.0116 s.


Fact: 3M of records consume 6GB of storage. This is enought to put everything on ARM LING VM using 32GB SD-card for storing 2.1MB of application bundle and 5MB or LING image. The memory consumption could be limited to 8GB of RAM per 3M records.

> kvs:dump().
                name         storage_type     memory       size
             account          disc_copies  120442109    3205762
             process          disc_copies      20274         26
             history          disc_copies       4190        111
             .                .                    .          .
             .                .                    .          .
Snapshot taken: {{2015,3,3},{17,39,34}}
ok

$ du -hs Mnesia.privat48@127.0.0.1
5861M

Business Processes

In business process management the key feature of is a compact process definitions. Here is example of Deposit Opening process definition in simple and clean BPMN 2.0 aware language. The web application is an client to ACT business process server, which hosts business process context. All the processes can be executed in attached console without web application.


  deposit_app() ->

    #process { name = 'Create Deposit Account',

        flows = [
            #sequenceFlow{source='Init',      target='Payment'},
            #sequenceFlow{source='Payment',   target='Signatory'},
            #sequenceFlow{source='Payment',   target='Process'},
            #sequenceFlow{source='Process',   target='Final'},
            #sequenceFlow{source='Signatory', target='Process'},
            #sequenceFlow{source='Signatory', target='Final'}
        ],

        tasks = [
            #userTask    { name='Init',      module = deposit },
            #userTask    { name='Signatory', module = deposit},
            #serviceTask { name='Payment',   module = deposit},
            #serviceTask { name='Process',   module = deposit},
            #endEvent    { name='Final'}
        ],

        beginEvent = 'Init',
        endEvent = 'Final',
        events = [
             #messageEvent{name="PaymentReceived"}
        ]
    }.

Thanks to compact process context the 1 million records of process states consume only 1GB of storage.

Heart System Capacity

Having measured the capacity of WebSocket front-end, we also state that performance of BPE engine and all PrivatBank service stack is outstanding. Here is sample business process that involves most external heavy services.


     EKBID = wf:qp(<<"ekbid">>,Req),
     Phone = #phone { number = "+38000000000" },
       Sid = #sid { sid = "15080" },
    Client = #client { phone = "+38000000000",
                       ekb_id = EKBID,
                       names = <<"Тест"/utf8>>,
                       surnames = <<"Тест"/utf8>> },

    Deposit = #deposit_app {
        program  = <<"DE00">>,
        currency = <<"980">>,
        rate     = [{rate,24},{bonus,0},{renewal_bonus,0.5}],
        duration = 12,
        type     = <<"TEST">>,
        amount   = 2,
        chargeDeposit = card,
        cardForCharge = #card{pan = <<"0000000000000000">>} },

    {ok,Pid} = bpe:start(deposit:def(), [ {dep_atom,'DE00_12_uah'},
                                          {notification, self()},
                                          {lang, ru},
                                          {channel,p24}]),

    {complete,'CheckSession'}    = bpe:amend(Pid, [Phone,Deposit,Client,Sid]),
    {complete,'CheckClient'}     = bpe:complete(Pid),
    {complete,'AcquireApp'}      = bpe:complete(Pid),
    {complete,'PrepareAccount'}  = bpe:complete(Pid),
    {complete,'CreateAccount'}   = bpe:complete(Pid),
    {complete,'CardPayment'}     = bpe:complete(Pid),
    {complete,'Payment'}         = bpe:complete(Pid),
    Sid1                         = bpe:doc(#sid{}, bpe:process(Pid)),
    {complete,'PaymentComplete'} = bpe:amend(Pid, Sid1#sid{web_pid= self()}),
                    'AcquireApp' = bpe:complete(Pid),

For storm we are using wrk utility that can go far beyond siege, httperf, ab and jmeter abilities. BPE engine is settled as external REST service through our rest application. BPE along with PrivatBank services can pass all steps for 500 customers in 1 second on single Depository Application node.


 $ wrk -c750 -d10s "http://processes.privat.bank/service/?ekbid=001"
 Running 10s test @ http://processes.privat.bank/service/?ekbid=001
   2 threads and 750 connections
   Thread Stats   Avg      Stdev     Max   +/- Stdev
      Latency     1.09s   391.52ms   2.00s    71.95%
      Req/Sec   277.85    188.50     1.11k    70.69%
   4925 requests in 10.08s, 860.91KB read
   Socket errors: connect 0, read 0, write 0, timeout 102
 Requests/sec:    588.78
 Transfer/sec:     85.44KB

   Table 1. Run test for each C for 1 minute
 +---------------+------------+-------------+
 | Connections   |  Finished  |  Timeouts   |
 +---------------+------------+-------------+
 |   200         |  200       |  0          |
 |   225         |  225       |  0          |
 |   250         |  250       |  0          |
 |   275         |  275       |  0          |
 |   300         |  300       |  0          |
 |   325         |  325       |  0          |
 |   350         |  350       |  0          |
 |   375         |  375       |  0          |
 |   400         |  400       |  0          |
 |   425         |  425       |  0          |
 |   450         |  450       |  0          |
 |   475         |  475       |  0          |
 |   500         |  500       |  0          |
 |   525         |  525       |  0          |
 |   550         |  523       |  27         |
 |   575         |  554       |  21         |
 |   600         |  567       |  33         |
 |   625         |  580       |  45         |
 +---------------+------------+-------------+

Made with ♡ for