Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/psamim/narayana-ruby
Use Narayana Transaction Manager in Ruby via REST
https://github.com/psamim/narayana-ruby
Last synced: about 1 month ago
JSON representation
Use Narayana Transaction Manager in Ruby via REST
- Host: GitHub
- URL: https://github.com/psamim/narayana-ruby
- Owner: psamim
- License: mit
- Created: 2015-07-17T19:23:58.000Z (over 9 years ago)
- Default Branch: master
- Last Pushed: 2015-07-24T07:32:10.000Z (over 9 years ago)
- Last Synced: 2024-05-10T22:00:51.993Z (8 months ago)
- Language: Ruby
- Homepage:
- Size: 750 KB
- Stars: 1
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
- License: LICENSE
Awesome Lists containing this project
README
#+LATEX_CLASS: assignment
#+OPTIONS: toc:nil
#+TITLE: Transaction Management Using Narayana In Ruby
#+AUTHOR: Samim Pezeshki* 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
#+BEGIN_SRC sh
$ docker-compose up
#+END_SRC#+LATEX: \vspace{2mm}
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.
#+LATEX: \vspace{2mm}
#+BEGIN_SRC ruby
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
#+END_SRC
#+LATEX: \vspace{2mm}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:
#+LATEX: \vspace{2mm}
#+BEGIN_SRC ruby
t1 = CheindTask.create
t2 = CheindTask.create# Creating a chain
t1.next = t2
t1.savet1.commit # Commits t1 and then t2
#+END_SRC#+LATEX: \vspace{2mm}
Nested transactions:
#+LATEX: \vspace{2mm}
#+BEGIN_SRC ruby
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.savet1.commit # Commits t1, then t2 and t3 in one transaction
#+END_SRC
#+LATEX: \vspace{2mm}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.#+CAPTION: Nested Transaction
#+ATTR_LATEX: :width 8cm
[[./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.#+CAPTION: Chained Transaction
#+ATTR_LATEX: :width 8cm
[[./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.