psamim / narayana-ruby

Use Narayana Transaction Manager in Ruby via REST

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Transaction Management Using Narayana In Ruby

Introduction

This application is a demo for using JBoss Narayana as a transaction manager in Ruby via Narayana REST API (rts subsystem). There are two transaction types implemented, nested and chained. The whole environment and application is packaged into Docker containers.

Requirements

  • docker
  • docker-compose

Installing and Running

$ docker-compose up

The first time, this may take a long time as we need to download Ruby base image, PostgreSQL and Wildfly application server and build the application. Descriptions about each Docker container is available at docker-compose.yml file.

Description

Narayana transaction manager is a part of Wildfly application server and can be used via its REST API When rts subsystem is enabled in Wildfly. Documentation about how rts API works and interacts is available at http://narayana.io/docs/project/index.html#d0e15500.

There were no implementation of Narayana API client in Ruby so I created it. Communication with Narayana is done through narayana/transaction class and HTTP requests. It can create a new transaction, enlist new participants and put or retrieve the transaction status.

Here is a sample code of how to use Transaction class.

tx = Transaction.new # Asks for a new transaction on Wildfly
tx.participate @resource  # Enlists resource in transction
tx.status # TransactionActive
tx.commit # Puts new status (TransactionCommitted) to Narayana for this transaction

I created a Task model using DataMapper ORM, and created the Task resource using Sinatra to respond to API calls from Wildfly server according to Narayana documentation. Each task can be type of Chained or Nested. Chained tasks can have one next and one prev task. When a chained task is commited, its next task is triggered. If one chained task fails, itself and its prev are rolled back.

Nested tasks can have multiple childs. When a nested task is commited, all of its children are triggered and commited in one transaction, all or none.

Using this Task model, we can test our transaction manager. Here is a sample code.

Chained transactions:

t1 = CheindTask.create
t2 = CheindTask.create

# Creating a chain
t1.next = t2
t1.save

t1.commit # Commits t1 and then t2

Nested transactions:

t1 = NestedTask.create
t2 = NestedTask.create
t3 = NestedTask.create fails: true

# Creating nested transaction
t1.childs << t2 # Add t2 to childs
t1.childs << t3
t1.save

t1.commit # Commits t1, then t2 and t3 in one transaction

Two sample scenarios are tested as a client in the app/client.rb file, one chained transaction and one nested. These scenarios are run in a separate process called client. Also we have another process called service which is our server talking to Narayana API on Wildfly server. All interactions are logged to console. A sample log file is provided with the source code in sample.log. Here is an example log.

./screenshot.png

The first column says that logs are from the Ruby container or Narayana container. The second column shows the name of the process, client or service.

Transaction Results

The results can be seen in the log file or reproduced by running the application.

The first scenario is a nested transaction as picture below. Transaction 4 aborts. As a result the root is commited, all siblings of T4 are rolled back, because they were in a transaction. Othere are not triggered because their parent has aborted.

./nested.png

The second scenario is a chained transaction as picture below. C2 aborts. Chain stops. C2 and its previous tasks should be rolled back in reverse order. Its next transaction is not triggered.

./chained.png

Technical Details

The whole application is in Ruby programming language. It uses Sinatra and Rack for serving the API client. It uses DataMapper as ORM for creating the Task model. PostgreSQL is used as our database for storing tasks.

The processes are described in the file Procfile and are managed by foreman to run as daemons. Each line in the Procfile describes one process of the application.

Docker Images

The application uses four docker images, postgres, wildfly-rts, dnsdock and ruby. The Ruby image is the main image for our application which is built by the provided Dockerfile. These images are in the public Docker hub registry and are downloaded and built automatically by the above command on the first time. The image dnsdock is used a DNS server between containers so that they can find each other.

These images are configured and run using docker-compose. The configuration is in the docker-compose.yml file.

About

Use Narayana Transaction Manager in Ruby via REST

License:MIT License


Languages

Language:Ruby 96.5%Language:Shell 3.5%