SlideShare a Scribd company logo
1 of 67
Download to read offline
Dive into SObjectizer-5.5
SObjectizer Team, May 2017
Ninth Part: Message Chains
(at v.5.5.19)
This is the next part of the series of presentations with deep
introduction into features of SObjectizer-5.5.
This part is dedicated to message chains feature.
The feature is relatively new.
It was introduced in v.5.5.13.
SObjectizer Team, May 2017
Introduction
SObjectizer Team, May 2017
The main purpose of message chains is to simplify
interaction between SObjectizer- and non-SObjectizer parts
of application.
SObjectizer Team, May 2017
It is pretty simple to send a message from a
non-SObjectizer-part to a SObjectizer-part of an application:
a message or signal can be sent to some mbox in a usual
way.
However, there was no a ready to use way to receive a reply
message or signal back. Because in non-SObjectizer-part
there couldn't be an entity behind mbox until v.5.5.13.
Then message chains (or mchains) were added...
SObjectizer Team, May 2017
Currently, it is possible to send a message or a signal to a
mchain from SObjectizer-part and receive and handle it in
non-SObjectizer-part via receive function.
Let's see how it looks like...
SObjectizer Team, May 2017
The agent which receives requests and sends replies:
class request_processor final : public so_5::agent_t
{
const so_5::mchain_t m_reply_to;
public :
request_processor( context_t ctx, so_5::mchain_t reply_to )
: so_5::agent_t{ ctx }, m_reply_to{ std::move(reply_to) }
{
// Requests will be sent from "handler" mbox.
so_subscribe( so_environment().create_mbox( "handler" ) )
.event( [&]( const request & msg ) {
... // Some request handling
// Sending a reply back.
so_5::send< reply >( m_reply_to, ... );
} );
...
}
...
};
SObjectizer Team, May 2017
The non-SObjectizer-part which sends requests and
receives responses:
so_5::wrapped_env_t sobj;
// mchain for replies.
// Simplest mchain without any limitations.
auto reply_ch = create_mchain( sobj );
// Launch request_processor and pass reply chain to it.
make_and_launch_request_processor( sobj, reply_ch );
// Sending requests and handling replies.
while( has_something_to_do() ) {
// Send new requests ordinary way.
so_5::send< request >( sobj.environment().create_mbox( "handler" ), ... );
// Receive and handle response.
receive( reply_ch, so_5::infinite_wait, []( const reply & msg ) { ... } );
}
SObjectizer Team, May 2017
mchain_t Type
SObjectizer Team, May 2017
The mchain_t type is similar to mbox_t.
It is an alias for a smart intrusive pointer to
abstract_message_chain_t.
It means that mchain created by create_mchain will be
destroyed automatically right after destruction of the last
mchain_t object pointing to it.
SObjectizer Team, May 2017
Types of mchains
SObjectizer Team, May 2017
There are two types of mchains:
1. Unlimited mchains. The mchain has no limitation for the
number of messages to be stored inside mchain. This
number is limited only by the amount of available
memory and by common sense of developer.
2. Limited mchains. The mchain has a strict limit for the
number of messages. It is just impossible to push yet
another message into full size-limited mchain.
SObjectizer Team, May 2017
The type of mchain is specified at creation of mchain
instance. Once created, the type of mchain cannot be
changed.
The type of mchain is specified by the content of
mchain_params_t instance passed to
environment_t::create_mchain method.
There are several helper functions which simplify creation of
mchains of various types...
SObjectizer Team, May 2017
Creation of an unlimited mchain:
so_5::mchain_t m1 = env.create_mchain(so_5::make_unlimited_mchain_params());
// Or via free helper function.
so_5::environment_t & env = ...;
so_5::mchain_t m1 = create_mchain(env);
// Or via another helper function.
so_5::wrapped_env_t sobj;
so_5::mchain_t m1 = create_mchain(sobj);
SObjectizer Team, May 2017
Creation of a size-limited mchain without waiting for attempt
of pushing new message to the full mchain:
so_5::mchain_t m2 = env.create_mchain(
so_5::make_limited_without_waiting_mchain_params(
// Capacity of mchain's message queue.
200,
// mchain's message queue will grow and shrink dynamically.
so_5::mchain_props::memory_usage_t::dynamic,
// Drop new message if mchain is full.
so_5::mchain_props::overflow_reaction_t::drop_newest));
// Or via free helper function.
so_5::mchain_t m2 = create_mchain(env, 200,
so_5::mchain_props::memory_usage_t::dynamic,
so_5::mchain_props::overflow_reaction_t::drop_newest);
SObjectizer Team, May 2017
Creation of a size-limited mchain with waiting for attempt of
pushing new message to full mchain:
so_5::mchain_t m3 = env.create_mchain(
so_5::make_limited_with_waiting_mchain_params(
// Capacity of mchain's message queue.
200,
// mchain's message queue will use preallocated fixed size storage
so_5::mchain_props::memory_usage_t::preallocated,
// New message will be dropped if mchain is full after a timeout.
so_5::mchain_props::overflow_reaction_t::drop_newest,
// A time for waiting for a free room in mchain if the mchain is full.
std::chrono::milliseconds(500)));
// Or via free helper function.
so_5::mchain_t m3 = create_mchain(env,
std::chrono::milliseconds(500),
200,
so_5::mchain_props::memory_usage_t::preallocated,
so_5::mchain_props::overflow_reaction_t::drop_newest);
SObjectizer Team, May 2017
More About Size-Limited mchains
SObjectizer Team, May 2017
Size-limited mchains are quite different from size-unlimited
mchains:
a size-limited mchain can't contain more messages than
the max capacity of the mchain.
So, there should be some reaction for attempt to add
another message to full mchain.
SObjectizer Team, May 2017
There are size-limited mchains which will wait for some time
for attempt of pushing new message to the full mchain.
If there is a free space in the mchain after that waiting then
the new message will be stored in the mchain.
Otherwise, the appropriate overload reaction will be
performed.
SObjectizer Team, May 2017
Also, there are size-limited mchains without any waiting time
for the full mchain.
If there is no free space in the mchain then the appropriate
overload reaction will be performed immediately.
SObjectizer Team, May 2017
There are four overload reactions which can be selected for
the mchain at the moment of its creation:
1. Dropping new message. It means that the new message will
be simply ignored.
2. Removing the oldest message from the mchain. It means that
the oldest message in the mchain will be removed and it will
not be processed.
3. Throwing an exception. The exception with error code
rc_msg_chain_overflow will be raised as a result of attempt of
pushing a new message to the full mchain.
4. Aborting the whole application by calling std::abort().
SObjectizer Team, May 2017
Another important property which should be specified for
size-limited mchain at the creation time is the type of
memory usage.
The memory for storing messages inside mchain can be
used dynamically: it will be allocated when mchain grows
and deallocated when mchain shrinks.
Likewise, the memory for mchain can be preallocated and
there will be a fixed-size buffer for messages. The buffer size
will not change during growth and shrinking of the mchain.
SObjectizer Team, May 2017
All these properties of size-limited mchains are controlled by
contents of the corresponding mchain_params_t:
so_5::mchain_t chain = env.create_mchain(
so_5::make_limited_with_waiting_mchain_params(
// No more than 200 messages in the mchain.
200,
// Memory will be preallocated.
so_5::mchain_props::memory_usage_t::preallocated,
// An exception will be thrown if there is no free room in the mchain.
so_5::mchain_props::overflow_reaction_t::throw_exception,
// But before throwing an exception there will be 500ms timeout
std::chrono::milliseconds(500)));
SObjectizer Team, May 2017
Receiving And Handling Messages From mchains
SObjectizer Team, May 2017
so_5::receive function which allows us to receive and handle
messages from mchain has two variants.
SObjectizer Team, May 2017
The first variant of receive takes mchain_t, timeout and the
list of message handlers:
so_5::mchain_t ch = env.create_mchain(...);
...
receive(ch, std::chrono::milliseconds(500),
[](const reply1 & r) {...},
[](const reply2 & r) {...},
...
[](const replyN & r) {...});
Note: because of ADL there is no need to write a call to receive as
so_5::receive. Appropriate receive version will be found in so_5
namespace automatically.
SObjectizer Team, May 2017
What does this call do?
receive(ch, std::chrono::milliseconds(500),
[](const reply1 & r) {...},
...
[](const replyN & r) {...});
It checks the mchain and waits for no more than 500ms if the
mchain is empty.
If the mchain is not empty it extracts just one message from the
mchain and tries to find an appropriate handler for it. If the handler
is found it is called. If the handler is not found then the extracted
message will be thrown out without any processing.
SObjectizer Team, May 2017
If the mchain is empty even after the specified timeout then
receive does nothing.
There are two special values which can be used as timeout:
● value so_5::no_wait specifies zero timeout. It means that
receive will not wait if the mchain is empty;
● value so_5::infinite_wait specifies endless waiting. The
return from receive will be on arrival of any message. Or
if the mchain is closed explicitly.
SObjectizer Team, May 2017
The second variant of receive is much more complicated:
receive(
// Extract no more than 1000 messages from queue.
// Take no more than 2s of total extraction and processing time.
from(chain).extract_n( 1000 ).total_time( seconds(2) ),
[](const reply1 & msg) {...},
[](const reply2 & msg) {...},
...
[](const reply3 & msg) {...} );
SObjectizer Team, May 2017
The advanced version of receive allows us to specify a
bunch of exit-conditions. For example:
● handle no more than N messages;
● extract no more than N messages (number of extracted
messages can be larger than the number of handled
messages);
● max waiting time in case of an empty mchain;
● max processing time for the whole receive;
● some external condition fulfilled.
SObjectizer Team, May 2017
Both receive versions return an object of
mchain_receive_result_t type.
Methods of that object allow us to get the number of extracted and
handled messages, and also the status of receive operation:
// Sending requests and handling replies.
while( has_something_to_do() ) {
// Send new requests ordinary way.
so_5::send< request >( sobj.environment().create_mbox( "handler" ), ... );
// Receive and handle response.
auto r = receive( from(reply_ch).empty_timeout( std::chrono::seconds(1) ),
[]( const reply & msg ) { ... } );
if( !r.handled() )
... // No reply arrived within 1s.
}
SObjectizer Team, May 2017
The receive functions family allows to receive and handle
messages from just one mchain.
But since v.5.5.16 there is select functions family which
allows to receive and handle messages from several
mchains...
SObjectizer Team, May 2017
The simplest variant of select is like the simplest variant of
receive: it extracts just one message.
so_5::mchain_t ch1 = env.create_mchain(...);
so_5::mchain_t ch2 = env.create_mchain(...);
so_5::mchain_t ch3 = env.create_mchain(...);
...
so_5::select(std::chrono::milliseconds(500),
case_(ch1, [](const reply1 & r) {...}),
case_(ch2, [](const reply2 & r) {...}),
case_(ch2, [](const reply3 & r) {...}));
The return from select will be on extraction of one message from
any of (ch1, ch2, ch3) mchains or if all mchains are empty within
500ms.
SObjectizer Team, May 2017
Also, there is more advanced version of select which can
receive and handle more than one message from mchains.
It receives a so_5::mchain_select_params_t objects with list
of conditions and returns control if any of those conditions
becomes true...
SObjectizer Team, May 2017
For example:
// Receive and handle 3 messages.
// It could be 3 messages from ch1. Or 2 messages from ch1 and 1 message
// from ch2. Or 1 message from ch1 and 2 messages from ch2. And so on...
// If there are no 3 messages in mchains the select will wait infinitely. A return from select
// will be after handling of 3 messages or if all mchains are closed explicitly.
select(from_all().handle_n(3),
case_( ch1, handler1_1, handler1_2, ...),
case_( ch2, handler2_1, handler2_2, ...));
// Receive and handle 3 messages.
// If there are no 3 messages in chains the select will wait no more than 200ms.
// A return from select will be after handling of 3 messages or if all mchains are closed
// explicitly, or if there are no messages for more than 200ms.
select(from_all().handle_n(3).empty_timeout(milliseconds(200)),
case_( ch1, handler1_1, handler1_2, ...),
case_( ch2, handler2_1, handler2_2, ...));
SObjectizer Team, May 2017
The advanced version of select allows to specify a bunch of
exit-conditions. For example:
● handle no more than N messages;
● extract no more than N messages (number of extracted
messages can be larger than the number of handled
messages);
● max waiting time in case of empty mchains;
● max processing time for the whole select;
● some external condition fulfilled.
SObjectizer Team, May 2017
The advanced version of select is very similar to advanced
version of receive. In fact almost all exit conditions for
advanced select are just twins for exit conditions of
advanced receive.
But select has yet another exit condition: select finishes its
work if all mchains become closed.
SObjectizer Team, May 2017
Both select versions return an object of
mchain_receive_result_t type.
Methods of that object allow us to get the number of extracted and
handled messages, and also the status of receive operation.
If no one message has been extracted because all mchains
become closed then select returns
extraction_status_t::chain_closed value as status of select
operation.
SObjectizer Team, May 2017
mchains Are MPMC Queues
SObjectizer Team, May 2017
Since v.5.5.16 mchains are implemented as Multi-Producer
and Multi-Consumer queues.
It means that it is possible to use the same mchain in parallel
calls to several receive and select on different threads.
This feature can be used for implementation of very simple
load-balancing scheme...
SObjectizer Team, May 2017
An example of a very simple load-balancing scheme:
void worker_thread(so_5::mchain_t ch) {
// Handle all messages until mchain will be closed.
receive(from(ch), handler1, handler2, handler3, ...);
}
...
// Message chain for passing messages to worker threads.
auto ch = create_mchain(env);
// Worker threads.
thread worker1{worker_thread, ch};
thread worker2{worker_thread, ch};
thread worker3{worker_thread, ch};
auto thr_joiner = auto_join(worker1, worker2, worker3);
// Send messages to workers.
while(has_some_work()) {
so_5::send< some_message >(ch, ...);
...
}
// Close chain and finish worker threads.
close_retain_content(ch);
SObjectizer Team, May 2017
Message Handlers
SObjectizer Team, May 2017
Message handlers which are passed to receive and select
functions family must be lambda-functions or functional
objects with the following format:
return_type handler( const message_type& );
return_type handler( message_type );
return_type handler( const so_5::mhood_t<message_type>& );
return_type handler( so_5::mhood_t<message_type> );
return_type handler( so_5::mhood_t<so_5::mutable_msg<message_type>> );
return_type handler( so_5::mutable_mhood_t<message_type> );
SObjectizer Team, May 2017
Some examples of handlers prototypes:
struct classical_message : public so_5::message_t { ... };
struct user_message { ... };
...
receive(chain, so_5::infinite_wait,
[](const classical_message & m) {...},
[](const user_message & m) {...},
[](const int & m) {...},
[](long m) {...});
SObjectizer Team, May 2017
The handler for signal of type signal_type can be created via
using so_5::handler<signal_type>() function:
struct stopped : public so_5::signal_t {};
struct waiting : public so_5::signal_t {};
...
receive(chain, so_5::infinite_wait,
[](const classical_message & m) {...},
[](const user_message & m) {...},
so_5::handler<stopped>( []{...} ),
so_5::handler<waiting>( []{...} ));
SObjectizer Team, May 2017
If so_5::mhood_t<T> message wrapper is used the type T
can be the type of message or signal:
struct check_status : public so_5::signal_t {};
struct reconfig { std::string config_file; };
...
receive(chain, so_5::infinite_wait,
[](const mhood_t<reconfig> & msg) {...},
[](mhood_t<check_status>) {...},
... );
SObjectizer Team, May 2017
The most important thing about message/signal handlers for
receive and select/case_ functions:
All message handlers must handle different message
types. It is an error if some handlers are defined for the
same message type.
SObjectizer Team, May 2017
Usage Of mchains With Send Functions
SObjectizer Team, May 2017
All traditional send-functions like send, send_delayed and
send_periodic work with mchains in the same way as they
work with mboxes.
SObjectizer Team, May 2017
It allows us to write the code in a traditional way:
// Sending a message.
so_5::send<my_message>(ch, ... /* some args for my_message's constructor */);
// Sending a delayed message.
so_5::send_delayed<my_message>(ch, std::chrono::milliseconds(200),
... /* some args for my_message's constructor */);
// Sending a periodic message.
auto timer_id = so_5::send_periodic<my_message>(ch,
std::chrono::milliseconds(200),
std::chrono::milliseconds(250),
... /* some args for my_message's constructor */);
SObjectizer Team, May 2017
The functions for performing service request, request_value
and request_future, work with mchains too.
It means that agent can make a service request to
non-SObjectizer part of an application and receive the result
of that request as usual.
SObjectizer Team, May 2017
Service request initiated by an agent:
// Somewhere in SObjectizer part of an application...
class worker : public so_5::agent_t {
const so_5::mchain_t m_request_ch;
...
void some_event_handler() {
auto f = so_5::request_future<response, request>(m_request_ch,
... /* some args for request's constructor */);
...
handle_response(f.get());
}
};
...
// Somewhere in non-SObjectizer part of an application...
const so_5::mchain_t request_ch = ...;
receive( from(request_ch).handle_n(1000),
[](const request & req) -> response {...}, ... );
SObjectizer Team, May 2017
mchains As mboxes
SObjectizer Team, May 2017
There is a method abstract_message_chain_t::as_mbox
which can represent mchain as almost ordinary mbox.
This method returns mbox_t and the mbox can be used for
sending messages and performing service request to the
mchain.
SObjectizer Team, May 2017
Method as_mbox can be useful if there is a necessity to hide
the fact of mchain existence.
For example, an agent inside SObjectizer’s part of an
application can receive mbox and think that there is another
agent on the opposite side...
SObjectizer Team, May 2017
mchain as mbox in SObjectizer-part of an application:
class request_processor final : public so_5::agent_t
{
const so_5::mbox_t m_reply_to;
public :
request_processor( context_t ctx, so_5::mbox_t reply_to )
: so_5::agent_t{ ctx }, m_reply_to{ std::move(reply_to) }
{
// Requests will be sent from "handler" mbox.
so_subscribe( so_environment().create_mbox( "handler" ) )
.event( [&]( const request & msg ) {
... // Some request handling
// Sending a reply back.
so_5::send< reply >( m_reply_to, ... );
} );
...
}
...
};
SObjectizer Team, May 2017
mchain as mbox in non-SObjectizer-part of an application:
so_5::wrapped_env_t sobj;
// mchain for replies.
// Simplest mchain without any limitations.
auto reply_ch = create_mchain( sobj );
// Launch request_processor and pass reply mchain to it.
// mchain will be represented as mbox.
make_and_launch_request_processor( sobj, reply_ch->as_mbox() );
// Sending requests and handling replies.
while( has_something_to_do() ) {
// Send new requests in an ordinary way.
so_5::send< request >( sobj.environment().create_mbox( "handler" ), ... );
// Receive and handle response.
receive( reply_ch, so_5::infinite_wait, []( const reply & msg ) { ... } );
}
SObjectizer Team, May 2017
The only difference between ordinary mbox created by
environment_t::create_mbox and mbox created by as_mbox
is that the second doesn’t allow to create subscriptions on it.
It means that agent request_processor from the example
above can't subscribe its event handlers to messages from
m_reply_to.
SObjectizer Team, May 2017
Usage Of mchains For Programming In CSP Style
SObjectizer Team, May 2017
mchains can be used for development of multithreaded
applications based on SObjectizer even without agents.
Threads can interact with each other by means of mchains in
CSP* style.
One thread can send messages to the mchain via ordinary
send function. Another thread can receive and handle them
via receive function.
SObjectizer Team, May 2017* https://en.wikipedia.org/wiki/Communicating_sequential_processes
Let's see how concurrent HelloWorld example looks like in
Go language...
...and in C++ with SObjectizer's mchains.
SObjectizer Team, May 2017
SObjectizer Team, May 2017
Go version (code before main):
package main
import "fmt"
C++ version (code before main):
#include <iostream>
#include <thread>
#include <so_5/all.hpp>
using namespace std;
using namespace std::literals;
using namespace so_5;
template< typename T >
void operator<<( mchain_t & to, T && o ) {
send< T >( to, forward<T>(o) );
}
template< typename T >
void operator>>( mchain_t & from, T & o ) {
receive(from, infinite_wait, [&o]( const T & msg ) { o = msg;
});
}
Please note that SObjectizer does not provide shorthands like Go's <- operator and
that’s why we need to define similar operators << and >> by hand.
SObjectizer Team, May 2017
Go version (function main):
func main() {
sayHello := make(chan string)
sayWorld := make(chan string)
quitter := make(chan string)
go func() {
for i := 0; i < 1000; i++ {
fmt.Print("Hello ")
sayWorld <- "Do it"
<-sayHello
}
sayWorld <- "Quit"
}()
go func() {
for {
var reply string
reply = <-sayWorld
if (reply == "Quit") {
break
}
fmt.Print("World!n")
sayHello <- "Do it"
}
quitter <- "Done"
}()
<-quitter
}
C++ version (function main):
int main() {
wrapped_env_t sobj;
auto say_hello = create_mchain( sobj );
auto say_world = create_mchain( sobj );
thread hello{ [&] {
string reply;
for( int i = 0; i != 1000; ++i ) {
cout << "Hello ";
say_world << "Do it"s;
say_hello >> reply;
}
say_world << "Quit"s;
} };
thread world{ [&] {
for(;;) {
string reply;
say_world >> reply;
if( "Quit" == reply )
break;
cout << "World" << endl;
say_hello << "Do it"s;
}
} };
auto_join(hello, world);
}
Some Final Words
SObjectizer Team, May 2017
mchains are relatively new addition to SObjectizer. They add
an easy way of communication between SObjectizer- and
non-SObjectizer-parts of an applications.
Likewise, mchains provide another way of solving
producer-consumer problem. For example, size-limited
mchains can be used for implementation of new
mechanisms of overload control.
It is worth noting that they allow us to write multithreaded
applications in CSP style without using agents.
SObjectizer Team, May 2017
Thus, mchains can lead to new ways of writing
SObjectizer-based programs.
Most likely, functionality of mchains will be extended in the
future versions of SObjectizer.
This presentation should not be considered as a
comprehensive guide to SObjectizer's mchains. For more
information on mchains please see the corresponding Wiki
section.
SObjectizer Team, May 2017
Additional Information:
Project’s home: http://sourceforge.net/projects/sobjectizer
Documentation: http://sourceforge.net/p/sobjectizer/wiki/
Forum: http://sourceforge.net/p/sobjectizer/discussion/
Google-group: https://groups.google.com/forum/#!forum/sobjectizer
Support: https://stiffstream.com

More Related Content

What's hot

Dive into SObjectizer 5.5. Fourth part. Exception
Dive into SObjectizer 5.5. Fourth part. ExceptionDive into SObjectizer 5.5. Fourth part. Exception
Dive into SObjectizer 5.5. Fourth part. ExceptionYauheni Akhotnikau
 
arataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world examplearataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world exampleYauheni Akhotnikau
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6Richard Jones
 
Creating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat ApplicationCreating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat ApplicationMicha Kops
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptKaty Slemon
 
Testing RESTful Webservices using the REST-assured framework
Testing RESTful Webservices using the REST-assured frameworkTesting RESTful Webservices using the REST-assured framework
Testing RESTful Webservices using the REST-assured frameworkMicha Kops
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSPVS-Studio
 
The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013
The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013
The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013Raimundas Banevičius
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4Richard Jones
 
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel ArchitectureReactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel ArchitectureGyuwon Yi
 
Implementation of fix messages for fix 5.0 sp2 and fixt1.1 specification
Implementation of fix messages for fix 5.0 sp2 and fixt1.1 specificationImplementation of fix messages for fix 5.0 sp2 and fixt1.1 specification
Implementation of fix messages for fix 5.0 sp2 and fixt1.1 specificationNeeraj Kaushik
 
Chain of Responsibility Pattern
Chain of Responsibility PatternChain of Responsibility Pattern
Chain of Responsibility PatternHüseyin Ergin
 
Study Notes: Google Percolator
Study Notes: Google PercolatorStudy Notes: Google Percolator
Study Notes: Google PercolatorGao Yunzhong
 
Qt Framework Events Signals Threads
Qt Framework Events Signals ThreadsQt Framework Events Signals Threads
Qt Framework Events Signals ThreadsNeera Mital
 

What's hot (20)

Dive into SObjectizer 5.5. Fourth part. Exception
Dive into SObjectizer 5.5. Fourth part. ExceptionDive into SObjectizer 5.5. Fourth part. Exception
Dive into SObjectizer 5.5. Fourth part. Exception
 
arataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world examplearataga. SObjectizer and RESTinio in action: a real-world example
arataga. SObjectizer and RESTinio in action: a real-world example
 
What's New In Python 2.6
What's New In Python 2.6What's New In Python 2.6
What's New In Python 2.6
 
Creating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat ApplicationCreating a Java EE 7 Websocket Chat Application
Creating a Java EE 7 Websocket Chat Application
 
How to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescriptHow to build to do app using vue composition api and vuex 4 with typescript
How to build to do app using vue composition api and vuex 4 with typescript
 
Testing RESTful Webservices using the REST-assured framework
Testing RESTful Webservices using the REST-assured frameworkTesting RESTful Webservices using the REST-assured framework
Testing RESTful Webservices using the REST-assured framework
 
Chain of responsibility
Chain of responsibilityChain of responsibility
Chain of responsibility
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMS
 
The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013
The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013
The Next Step in AS3 Framework Evolution - FITC Amsterdam 2013
 
What's New In Python 2.4
What's New In Python 2.4What's New In Python 2.4
What's New In Python 2.4
 
Reactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel ArchitectureReactive Model-View-ViewModel Architecture
Reactive Model-View-ViewModel Architecture
 
mvcExpress training course : part1
mvcExpress training course : part1mvcExpress training course : part1
mvcExpress training course : part1
 
Mvc express presentation
Mvc express presentationMvc express presentation
Mvc express presentation
 
Implementation of fix messages for fix 5.0 sp2 and fixt1.1 specification
Implementation of fix messages for fix 5.0 sp2 and fixt1.1 specificationImplementation of fix messages for fix 5.0 sp2 and fixt1.1 specification
Implementation of fix messages for fix 5.0 sp2 and fixt1.1 specification
 
Chain of Responsibility Pattern
Chain of Responsibility PatternChain of Responsibility Pattern
Chain of Responsibility Pattern
 
Complete Java Course
Complete Java CourseComplete Java Course
Complete Java Course
 
Study Notes: Google Percolator
Study Notes: Google PercolatorStudy Notes: Google Percolator
Study Notes: Google Percolator
 
Qt Framework Events Signals Threads
Qt Framework Events Signals ThreadsQt Framework Events Signals Threads
Qt Framework Events Signals Threads
 
C++ Functions
C++ FunctionsC++ Functions
C++ Functions
 
C# simplified
C#  simplifiedC#  simplified
C# simplified
 

Similar to Dive into SObjectizer 5.5. Ninth Part: Message Chains

What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9Yauheni Akhotnikau
 
Java message service
Java message serviceJava message service
Java message serviceVeeramani S
 
What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)Yauheni Akhotnikau
 
Java Messaging Services
Java Messaging ServicesJava Messaging Services
Java Messaging Serviceskumar gaurav
 
What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)Yauheni Akhotnikau
 
test validation
test validationtest validation
test validationtechweb08
 
Test DB user
Test DB userTest DB user
Test DB usertechweb08
 
Building a blockchain part 3
Building a blockchain part 3Building a blockchain part 3
Building a blockchain part 3juliomacr
 
Safe Clearing of Private Data
Safe Clearing of Private DataSafe Clearing of Private Data
Safe Clearing of Private DataPVS-Studio
 
Iterative processing using the for each scope in
Iterative processing using the for each scope inIterative processing using the for each scope in
Iterative processing using the for each scope inAnkit Lawaniya
 
communication among tasks in advanced system architecture
communication among tasks in advanced system architecturecommunication among tasks in advanced system architecture
communication among tasks in advanced system architectureRoslinJoseph
 
The PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL ProxyThe PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL ProxyUlf Wendel
 
Using RAG to create your own Podcast conversations.pdf
Using RAG to create your own Podcast conversations.pdfUsing RAG to create your own Podcast conversations.pdf
Using RAG to create your own Podcast conversations.pdfRichard Rodger
 

Similar to Dive into SObjectizer 5.5. Ninth Part: Message Chains (20)

What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9
 
Java message service
Java message serviceJava message service
Java message service
 
What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)What is SObjectizer 5.6 (at v.5.6.0)
What is SObjectizer 5.6 (at v.5.6.0)
 
Java Messaging Services
Java Messaging ServicesJava Messaging Services
Java Messaging Services
 
Chapter 04: Eclipse Vert.x - Message Based Microservices
Chapter 04: Eclipse Vert.x - Message Based MicroservicesChapter 04: Eclipse Vert.x - Message Based Microservices
Chapter 04: Eclipse Vert.x - Message Based Microservices
 
Intake 37 5
Intake 37 5Intake 37 5
Intake 37 5
 
What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)What is SObjectizer 5.7 (at v.5.7.0)
What is SObjectizer 5.7 (at v.5.7.0)
 
test validation
test validationtest validation
test validation
 
Test DB user
Test DB userTest DB user
Test DB user
 
Building a blockchain part 3
Building a blockchain part 3Building a blockchain part 3
Building a blockchain part 3
 
Designing Modules in Python
Designing Modules in PythonDesigning Modules in Python
Designing Modules in Python
 
Safe Clearing of Private Data
Safe Clearing of Private DataSafe Clearing of Private Data
Safe Clearing of Private Data
 
Iterative processing using the for each scope in
Iterative processing using the for each scope inIterative processing using the for each scope in
Iterative processing using the for each scope in
 
Lecture 11 compiler ii
Lecture 11 compiler iiLecture 11 compiler ii
Lecture 11 compiler ii
 
Typescript Basics
Typescript BasicsTypescript Basics
Typescript Basics
 
communication among tasks in advanced system architecture
communication among tasks in advanced system architecturecommunication among tasks in advanced system architecture
communication among tasks in advanced system architecture
 
Well You Ought To Know (WYOTK) FP&A Automation Series
Well You Ought To Know (WYOTK) FP&A Automation SeriesWell You Ought To Know (WYOTK) FP&A Automation Series
Well You Ought To Know (WYOTK) FP&A Automation Series
 
The PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL ProxyThe PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
The PHP mysqlnd plugin talk - plugins an alternative to MySQL Proxy
 
Using RAG to create your own Podcast conversations.pdf
Using RAG to create your own Podcast conversations.pdfUsing RAG to create your own Podcast conversations.pdf
Using RAG to create your own Podcast conversations.pdf
 
NodeJs Session02
NodeJs Session02NodeJs Session02
NodeJs Session02
 

More from Yauheni Akhotnikau

Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)Yauheni Akhotnikau
 
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...Yauheni Akhotnikau
 
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...Yauheni Akhotnikau
 
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...Yauheni Akhotnikau
 
Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Yauheni Akhotnikau
 
25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My Eyes25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My EyesYauheni Akhotnikau
 
GECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them allGECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them allYauheni Akhotnikau
 
Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?Yauheni Akhotnikau
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Yauheni Akhotnikau
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Yauheni Akhotnikau
 
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Yauheni Akhotnikau
 
What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8Yauheni Akhotnikau
 
Погружение в SObjectizer 5.5. Вводная часть
Погружение в SObjectizer 5.5. Вводная частьПогружение в SObjectizer 5.5. Вводная часть
Погружение в SObjectizer 5.5. Вводная частьYauheni Akhotnikau
 

More from Yauheni Akhotnikau (14)

Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)Actor Model and C++: what, why and how? (March 2020 Edition)
Actor Model and C++: what, why and how? (March 2020 Edition)
 
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
[C++ CoreHard Autumn 2018] Actors vs CSP vs Task...
 
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
Shrimp: A Rather Practical Example Of Application Development With RESTinio a...
 
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
 
Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?
 
25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My Eyes25 Years of C++ History Flashed in Front of My Eyes
25 Years of C++ History Flashed in Front of My Eyes
 
GECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them allGECon 2017: C++ - a Monster that no one likes but that will outlast them all
GECon 2017: C++ - a Monster that no one likes but that will outlast them all
 
Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?Actor Model and C++: what, why and how?
Actor Model and C++: what, why and how?
 
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++
 
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?
 
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?
 
What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8What’s new in SObjectizer 5.5.8
What’s new in SObjectizer 5.5.8
 
Погружение в SObjectizer 5.5. Вводная часть
Погружение в SObjectizer 5.5. Вводная частьПогружение в SObjectizer 5.5. Вводная часть
Погружение в SObjectizer 5.5. Вводная часть
 
Обзор SObjectizer 5.5
Обзор SObjectizer 5.5Обзор SObjectizer 5.5
Обзор SObjectizer 5.5
 

Recently uploaded

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 

Recently uploaded (20)

GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 

Dive into SObjectizer 5.5. Ninth Part: Message Chains

  • 1. Dive into SObjectizer-5.5 SObjectizer Team, May 2017 Ninth Part: Message Chains (at v.5.5.19)
  • 2. This is the next part of the series of presentations with deep introduction into features of SObjectizer-5.5. This part is dedicated to message chains feature. The feature is relatively new. It was introduced in v.5.5.13. SObjectizer Team, May 2017
  • 4. The main purpose of message chains is to simplify interaction between SObjectizer- and non-SObjectizer parts of application. SObjectizer Team, May 2017
  • 5. It is pretty simple to send a message from a non-SObjectizer-part to a SObjectizer-part of an application: a message or signal can be sent to some mbox in a usual way. However, there was no a ready to use way to receive a reply message or signal back. Because in non-SObjectizer-part there couldn't be an entity behind mbox until v.5.5.13. Then message chains (or mchains) were added... SObjectizer Team, May 2017
  • 6. Currently, it is possible to send a message or a signal to a mchain from SObjectizer-part and receive and handle it in non-SObjectizer-part via receive function. Let's see how it looks like... SObjectizer Team, May 2017
  • 7. The agent which receives requests and sends replies: class request_processor final : public so_5::agent_t { const so_5::mchain_t m_reply_to; public : request_processor( context_t ctx, so_5::mchain_t reply_to ) : so_5::agent_t{ ctx }, m_reply_to{ std::move(reply_to) } { // Requests will be sent from "handler" mbox. so_subscribe( so_environment().create_mbox( "handler" ) ) .event( [&]( const request & msg ) { ... // Some request handling // Sending a reply back. so_5::send< reply >( m_reply_to, ... ); } ); ... } ... }; SObjectizer Team, May 2017
  • 8. The non-SObjectizer-part which sends requests and receives responses: so_5::wrapped_env_t sobj; // mchain for replies. // Simplest mchain without any limitations. auto reply_ch = create_mchain( sobj ); // Launch request_processor and pass reply chain to it. make_and_launch_request_processor( sobj, reply_ch ); // Sending requests and handling replies. while( has_something_to_do() ) { // Send new requests ordinary way. so_5::send< request >( sobj.environment().create_mbox( "handler" ), ... ); // Receive and handle response. receive( reply_ch, so_5::infinite_wait, []( const reply & msg ) { ... } ); } SObjectizer Team, May 2017
  • 10. The mchain_t type is similar to mbox_t. It is an alias for a smart intrusive pointer to abstract_message_chain_t. It means that mchain created by create_mchain will be destroyed automatically right after destruction of the last mchain_t object pointing to it. SObjectizer Team, May 2017
  • 12. There are two types of mchains: 1. Unlimited mchains. The mchain has no limitation for the number of messages to be stored inside mchain. This number is limited only by the amount of available memory and by common sense of developer. 2. Limited mchains. The mchain has a strict limit for the number of messages. It is just impossible to push yet another message into full size-limited mchain. SObjectizer Team, May 2017
  • 13. The type of mchain is specified at creation of mchain instance. Once created, the type of mchain cannot be changed. The type of mchain is specified by the content of mchain_params_t instance passed to environment_t::create_mchain method. There are several helper functions which simplify creation of mchains of various types... SObjectizer Team, May 2017
  • 14. Creation of an unlimited mchain: so_5::mchain_t m1 = env.create_mchain(so_5::make_unlimited_mchain_params()); // Or via free helper function. so_5::environment_t & env = ...; so_5::mchain_t m1 = create_mchain(env); // Or via another helper function. so_5::wrapped_env_t sobj; so_5::mchain_t m1 = create_mchain(sobj); SObjectizer Team, May 2017
  • 15. Creation of a size-limited mchain without waiting for attempt of pushing new message to the full mchain: so_5::mchain_t m2 = env.create_mchain( so_5::make_limited_without_waiting_mchain_params( // Capacity of mchain's message queue. 200, // mchain's message queue will grow and shrink dynamically. so_5::mchain_props::memory_usage_t::dynamic, // Drop new message if mchain is full. so_5::mchain_props::overflow_reaction_t::drop_newest)); // Or via free helper function. so_5::mchain_t m2 = create_mchain(env, 200, so_5::mchain_props::memory_usage_t::dynamic, so_5::mchain_props::overflow_reaction_t::drop_newest); SObjectizer Team, May 2017
  • 16. Creation of a size-limited mchain with waiting for attempt of pushing new message to full mchain: so_5::mchain_t m3 = env.create_mchain( so_5::make_limited_with_waiting_mchain_params( // Capacity of mchain's message queue. 200, // mchain's message queue will use preallocated fixed size storage so_5::mchain_props::memory_usage_t::preallocated, // New message will be dropped if mchain is full after a timeout. so_5::mchain_props::overflow_reaction_t::drop_newest, // A time for waiting for a free room in mchain if the mchain is full. std::chrono::milliseconds(500))); // Or via free helper function. so_5::mchain_t m3 = create_mchain(env, std::chrono::milliseconds(500), 200, so_5::mchain_props::memory_usage_t::preallocated, so_5::mchain_props::overflow_reaction_t::drop_newest); SObjectizer Team, May 2017
  • 17. More About Size-Limited mchains SObjectizer Team, May 2017
  • 18. Size-limited mchains are quite different from size-unlimited mchains: a size-limited mchain can't contain more messages than the max capacity of the mchain. So, there should be some reaction for attempt to add another message to full mchain. SObjectizer Team, May 2017
  • 19. There are size-limited mchains which will wait for some time for attempt of pushing new message to the full mchain. If there is a free space in the mchain after that waiting then the new message will be stored in the mchain. Otherwise, the appropriate overload reaction will be performed. SObjectizer Team, May 2017
  • 20. Also, there are size-limited mchains without any waiting time for the full mchain. If there is no free space in the mchain then the appropriate overload reaction will be performed immediately. SObjectizer Team, May 2017
  • 21. There are four overload reactions which can be selected for the mchain at the moment of its creation: 1. Dropping new message. It means that the new message will be simply ignored. 2. Removing the oldest message from the mchain. It means that the oldest message in the mchain will be removed and it will not be processed. 3. Throwing an exception. The exception with error code rc_msg_chain_overflow will be raised as a result of attempt of pushing a new message to the full mchain. 4. Aborting the whole application by calling std::abort(). SObjectizer Team, May 2017
  • 22. Another important property which should be specified for size-limited mchain at the creation time is the type of memory usage. The memory for storing messages inside mchain can be used dynamically: it will be allocated when mchain grows and deallocated when mchain shrinks. Likewise, the memory for mchain can be preallocated and there will be a fixed-size buffer for messages. The buffer size will not change during growth and shrinking of the mchain. SObjectizer Team, May 2017
  • 23. All these properties of size-limited mchains are controlled by contents of the corresponding mchain_params_t: so_5::mchain_t chain = env.create_mchain( so_5::make_limited_with_waiting_mchain_params( // No more than 200 messages in the mchain. 200, // Memory will be preallocated. so_5::mchain_props::memory_usage_t::preallocated, // An exception will be thrown if there is no free room in the mchain. so_5::mchain_props::overflow_reaction_t::throw_exception, // But before throwing an exception there will be 500ms timeout std::chrono::milliseconds(500))); SObjectizer Team, May 2017
  • 24. Receiving And Handling Messages From mchains SObjectizer Team, May 2017
  • 25. so_5::receive function which allows us to receive and handle messages from mchain has two variants. SObjectizer Team, May 2017
  • 26. The first variant of receive takes mchain_t, timeout and the list of message handlers: so_5::mchain_t ch = env.create_mchain(...); ... receive(ch, std::chrono::milliseconds(500), [](const reply1 & r) {...}, [](const reply2 & r) {...}, ... [](const replyN & r) {...}); Note: because of ADL there is no need to write a call to receive as so_5::receive. Appropriate receive version will be found in so_5 namespace automatically. SObjectizer Team, May 2017
  • 27. What does this call do? receive(ch, std::chrono::milliseconds(500), [](const reply1 & r) {...}, ... [](const replyN & r) {...}); It checks the mchain and waits for no more than 500ms if the mchain is empty. If the mchain is not empty it extracts just one message from the mchain and tries to find an appropriate handler for it. If the handler is found it is called. If the handler is not found then the extracted message will be thrown out without any processing. SObjectizer Team, May 2017
  • 28. If the mchain is empty even after the specified timeout then receive does nothing. There are two special values which can be used as timeout: ● value so_5::no_wait specifies zero timeout. It means that receive will not wait if the mchain is empty; ● value so_5::infinite_wait specifies endless waiting. The return from receive will be on arrival of any message. Or if the mchain is closed explicitly. SObjectizer Team, May 2017
  • 29. The second variant of receive is much more complicated: receive( // Extract no more than 1000 messages from queue. // Take no more than 2s of total extraction and processing time. from(chain).extract_n( 1000 ).total_time( seconds(2) ), [](const reply1 & msg) {...}, [](const reply2 & msg) {...}, ... [](const reply3 & msg) {...} ); SObjectizer Team, May 2017
  • 30. The advanced version of receive allows us to specify a bunch of exit-conditions. For example: ● handle no more than N messages; ● extract no more than N messages (number of extracted messages can be larger than the number of handled messages); ● max waiting time in case of an empty mchain; ● max processing time for the whole receive; ● some external condition fulfilled. SObjectizer Team, May 2017
  • 31. Both receive versions return an object of mchain_receive_result_t type. Methods of that object allow us to get the number of extracted and handled messages, and also the status of receive operation: // Sending requests and handling replies. while( has_something_to_do() ) { // Send new requests ordinary way. so_5::send< request >( sobj.environment().create_mbox( "handler" ), ... ); // Receive and handle response. auto r = receive( from(reply_ch).empty_timeout( std::chrono::seconds(1) ), []( const reply & msg ) { ... } ); if( !r.handled() ) ... // No reply arrived within 1s. } SObjectizer Team, May 2017
  • 32. The receive functions family allows to receive and handle messages from just one mchain. But since v.5.5.16 there is select functions family which allows to receive and handle messages from several mchains... SObjectizer Team, May 2017
  • 33. The simplest variant of select is like the simplest variant of receive: it extracts just one message. so_5::mchain_t ch1 = env.create_mchain(...); so_5::mchain_t ch2 = env.create_mchain(...); so_5::mchain_t ch3 = env.create_mchain(...); ... so_5::select(std::chrono::milliseconds(500), case_(ch1, [](const reply1 & r) {...}), case_(ch2, [](const reply2 & r) {...}), case_(ch2, [](const reply3 & r) {...})); The return from select will be on extraction of one message from any of (ch1, ch2, ch3) mchains or if all mchains are empty within 500ms. SObjectizer Team, May 2017
  • 34. Also, there is more advanced version of select which can receive and handle more than one message from mchains. It receives a so_5::mchain_select_params_t objects with list of conditions and returns control if any of those conditions becomes true... SObjectizer Team, May 2017
  • 35. For example: // Receive and handle 3 messages. // It could be 3 messages from ch1. Or 2 messages from ch1 and 1 message // from ch2. Or 1 message from ch1 and 2 messages from ch2. And so on... // If there are no 3 messages in mchains the select will wait infinitely. A return from select // will be after handling of 3 messages or if all mchains are closed explicitly. select(from_all().handle_n(3), case_( ch1, handler1_1, handler1_2, ...), case_( ch2, handler2_1, handler2_2, ...)); // Receive and handle 3 messages. // If there are no 3 messages in chains the select will wait no more than 200ms. // A return from select will be after handling of 3 messages or if all mchains are closed // explicitly, or if there are no messages for more than 200ms. select(from_all().handle_n(3).empty_timeout(milliseconds(200)), case_( ch1, handler1_1, handler1_2, ...), case_( ch2, handler2_1, handler2_2, ...)); SObjectizer Team, May 2017
  • 36. The advanced version of select allows to specify a bunch of exit-conditions. For example: ● handle no more than N messages; ● extract no more than N messages (number of extracted messages can be larger than the number of handled messages); ● max waiting time in case of empty mchains; ● max processing time for the whole select; ● some external condition fulfilled. SObjectizer Team, May 2017
  • 37. The advanced version of select is very similar to advanced version of receive. In fact almost all exit conditions for advanced select are just twins for exit conditions of advanced receive. But select has yet another exit condition: select finishes its work if all mchains become closed. SObjectizer Team, May 2017
  • 38. Both select versions return an object of mchain_receive_result_t type. Methods of that object allow us to get the number of extracted and handled messages, and also the status of receive operation. If no one message has been extracted because all mchains become closed then select returns extraction_status_t::chain_closed value as status of select operation. SObjectizer Team, May 2017
  • 39. mchains Are MPMC Queues SObjectizer Team, May 2017
  • 40. Since v.5.5.16 mchains are implemented as Multi-Producer and Multi-Consumer queues. It means that it is possible to use the same mchain in parallel calls to several receive and select on different threads. This feature can be used for implementation of very simple load-balancing scheme... SObjectizer Team, May 2017
  • 41. An example of a very simple load-balancing scheme: void worker_thread(so_5::mchain_t ch) { // Handle all messages until mchain will be closed. receive(from(ch), handler1, handler2, handler3, ...); } ... // Message chain for passing messages to worker threads. auto ch = create_mchain(env); // Worker threads. thread worker1{worker_thread, ch}; thread worker2{worker_thread, ch}; thread worker3{worker_thread, ch}; auto thr_joiner = auto_join(worker1, worker2, worker3); // Send messages to workers. while(has_some_work()) { so_5::send< some_message >(ch, ...); ... } // Close chain and finish worker threads. close_retain_content(ch); SObjectizer Team, May 2017
  • 43. Message handlers which are passed to receive and select functions family must be lambda-functions or functional objects with the following format: return_type handler( const message_type& ); return_type handler( message_type ); return_type handler( const so_5::mhood_t<message_type>& ); return_type handler( so_5::mhood_t<message_type> ); return_type handler( so_5::mhood_t<so_5::mutable_msg<message_type>> ); return_type handler( so_5::mutable_mhood_t<message_type> ); SObjectizer Team, May 2017
  • 44. Some examples of handlers prototypes: struct classical_message : public so_5::message_t { ... }; struct user_message { ... }; ... receive(chain, so_5::infinite_wait, [](const classical_message & m) {...}, [](const user_message & m) {...}, [](const int & m) {...}, [](long m) {...}); SObjectizer Team, May 2017
  • 45. The handler for signal of type signal_type can be created via using so_5::handler<signal_type>() function: struct stopped : public so_5::signal_t {}; struct waiting : public so_5::signal_t {}; ... receive(chain, so_5::infinite_wait, [](const classical_message & m) {...}, [](const user_message & m) {...}, so_5::handler<stopped>( []{...} ), so_5::handler<waiting>( []{...} )); SObjectizer Team, May 2017
  • 46. If so_5::mhood_t<T> message wrapper is used the type T can be the type of message or signal: struct check_status : public so_5::signal_t {}; struct reconfig { std::string config_file; }; ... receive(chain, so_5::infinite_wait, [](const mhood_t<reconfig> & msg) {...}, [](mhood_t<check_status>) {...}, ... ); SObjectizer Team, May 2017
  • 47. The most important thing about message/signal handlers for receive and select/case_ functions: All message handlers must handle different message types. It is an error if some handlers are defined for the same message type. SObjectizer Team, May 2017
  • 48. Usage Of mchains With Send Functions SObjectizer Team, May 2017
  • 49. All traditional send-functions like send, send_delayed and send_periodic work with mchains in the same way as they work with mboxes. SObjectizer Team, May 2017
  • 50. It allows us to write the code in a traditional way: // Sending a message. so_5::send<my_message>(ch, ... /* some args for my_message's constructor */); // Sending a delayed message. so_5::send_delayed<my_message>(ch, std::chrono::milliseconds(200), ... /* some args for my_message's constructor */); // Sending a periodic message. auto timer_id = so_5::send_periodic<my_message>(ch, std::chrono::milliseconds(200), std::chrono::milliseconds(250), ... /* some args for my_message's constructor */); SObjectizer Team, May 2017
  • 51. The functions for performing service request, request_value and request_future, work with mchains too. It means that agent can make a service request to non-SObjectizer part of an application and receive the result of that request as usual. SObjectizer Team, May 2017
  • 52. Service request initiated by an agent: // Somewhere in SObjectizer part of an application... class worker : public so_5::agent_t { const so_5::mchain_t m_request_ch; ... void some_event_handler() { auto f = so_5::request_future<response, request>(m_request_ch, ... /* some args for request's constructor */); ... handle_response(f.get()); } }; ... // Somewhere in non-SObjectizer part of an application... const so_5::mchain_t request_ch = ...; receive( from(request_ch).handle_n(1000), [](const request & req) -> response {...}, ... ); SObjectizer Team, May 2017
  • 54. There is a method abstract_message_chain_t::as_mbox which can represent mchain as almost ordinary mbox. This method returns mbox_t and the mbox can be used for sending messages and performing service request to the mchain. SObjectizer Team, May 2017
  • 55. Method as_mbox can be useful if there is a necessity to hide the fact of mchain existence. For example, an agent inside SObjectizer’s part of an application can receive mbox and think that there is another agent on the opposite side... SObjectizer Team, May 2017
  • 56. mchain as mbox in SObjectizer-part of an application: class request_processor final : public so_5::agent_t { const so_5::mbox_t m_reply_to; public : request_processor( context_t ctx, so_5::mbox_t reply_to ) : so_5::agent_t{ ctx }, m_reply_to{ std::move(reply_to) } { // Requests will be sent from "handler" mbox. so_subscribe( so_environment().create_mbox( "handler" ) ) .event( [&]( const request & msg ) { ... // Some request handling // Sending a reply back. so_5::send< reply >( m_reply_to, ... ); } ); ... } ... }; SObjectizer Team, May 2017
  • 57. mchain as mbox in non-SObjectizer-part of an application: so_5::wrapped_env_t sobj; // mchain for replies. // Simplest mchain without any limitations. auto reply_ch = create_mchain( sobj ); // Launch request_processor and pass reply mchain to it. // mchain will be represented as mbox. make_and_launch_request_processor( sobj, reply_ch->as_mbox() ); // Sending requests and handling replies. while( has_something_to_do() ) { // Send new requests in an ordinary way. so_5::send< request >( sobj.environment().create_mbox( "handler" ), ... ); // Receive and handle response. receive( reply_ch, so_5::infinite_wait, []( const reply & msg ) { ... } ); } SObjectizer Team, May 2017
  • 58. The only difference between ordinary mbox created by environment_t::create_mbox and mbox created by as_mbox is that the second doesn’t allow to create subscriptions on it. It means that agent request_processor from the example above can't subscribe its event handlers to messages from m_reply_to. SObjectizer Team, May 2017
  • 59. Usage Of mchains For Programming In CSP Style SObjectizer Team, May 2017
  • 60. mchains can be used for development of multithreaded applications based on SObjectizer even without agents. Threads can interact with each other by means of mchains in CSP* style. One thread can send messages to the mchain via ordinary send function. Another thread can receive and handle them via receive function. SObjectizer Team, May 2017* https://en.wikipedia.org/wiki/Communicating_sequential_processes
  • 61. Let's see how concurrent HelloWorld example looks like in Go language... ...and in C++ with SObjectizer's mchains. SObjectizer Team, May 2017
  • 62. SObjectizer Team, May 2017 Go version (code before main): package main import "fmt" C++ version (code before main): #include <iostream> #include <thread> #include <so_5/all.hpp> using namespace std; using namespace std::literals; using namespace so_5; template< typename T > void operator<<( mchain_t & to, T && o ) { send< T >( to, forward<T>(o) ); } template< typename T > void operator>>( mchain_t & from, T & o ) { receive(from, infinite_wait, [&o]( const T & msg ) { o = msg; }); } Please note that SObjectizer does not provide shorthands like Go's <- operator and that’s why we need to define similar operators << and >> by hand.
  • 63. SObjectizer Team, May 2017 Go version (function main): func main() { sayHello := make(chan string) sayWorld := make(chan string) quitter := make(chan string) go func() { for i := 0; i < 1000; i++ { fmt.Print("Hello ") sayWorld <- "Do it" <-sayHello } sayWorld <- "Quit" }() go func() { for { var reply string reply = <-sayWorld if (reply == "Quit") { break } fmt.Print("World!n") sayHello <- "Do it" } quitter <- "Done" }() <-quitter } C++ version (function main): int main() { wrapped_env_t sobj; auto say_hello = create_mchain( sobj ); auto say_world = create_mchain( sobj ); thread hello{ [&] { string reply; for( int i = 0; i != 1000; ++i ) { cout << "Hello "; say_world << "Do it"s; say_hello >> reply; } say_world << "Quit"s; } }; thread world{ [&] { for(;;) { string reply; say_world >> reply; if( "Quit" == reply ) break; cout << "World" << endl; say_hello << "Do it"s; } } }; auto_join(hello, world); }
  • 65. mchains are relatively new addition to SObjectizer. They add an easy way of communication between SObjectizer- and non-SObjectizer-parts of an applications. Likewise, mchains provide another way of solving producer-consumer problem. For example, size-limited mchains can be used for implementation of new mechanisms of overload control. It is worth noting that they allow us to write multithreaded applications in CSP style without using agents. SObjectizer Team, May 2017
  • 66. Thus, mchains can lead to new ways of writing SObjectizer-based programs. Most likely, functionality of mchains will be extended in the future versions of SObjectizer. This presentation should not be considered as a comprehensive guide to SObjectizer's mchains. For more information on mchains please see the corresponding Wiki section. SObjectizer Team, May 2017
  • 67. Additional Information: Project’s home: http://sourceforge.net/projects/sobjectizer Documentation: http://sourceforge.net/p/sobjectizer/wiki/ Forum: http://sourceforge.net/p/sobjectizer/discussion/ Google-group: https://groups.google.com/forum/#!forum/sobjectizer Support: https://stiffstream.com