SlideShare a Scribd company logo
arataga
SObjectizer and RESTinio in action:
a real-world example
Foreword
2
What is 'arataga'
arataga is a fully working prototype of performant socks5+http/1.1 proxy server
targeted a case when thousands of entry points have to be opened.
3
A way to open source
arataga was in development in the summer of 2020 by stiffsteam for a customer
who wanted to replace its own old proxy server.
For some reason, the customer abandoned the project.
But almost all functionality we wanted to have was already implemented, so we
decided to open source arataga.
4
Why we open sourced aragata?
It's a shame to throw away a product that our hard work was put into.
Maybe the results of our work will be useful for somebody.
It's also a perfect showcase of how we write code using SObjectizer and
RESTinio.
5
Where arataga lives?
https://github.com/Stiffstream/arataga
6
Requirements for arataga
and design decisions
7
Projects requirements
● thousands of entry-points (unique pairs of IP-address+TCP-port).
At least 8K entry-points should have been supported at the beginning;
● tens of thousands of users can work with the proxy simultaneously (40K
parallel connections is a normal workload);
● user connections/disconnections at the rate of 1,000+ new connections per
second;
● bandwidth had to be limited for client connections, including limits for a
particular domains;
● the configuration and lists of allowed users must be received
via a special HTTP entry point.
8
Multithreading or multiprocessing
Tens of thousands of connections are expected. They hardly be handled in a
single-thread application.
We didn't go in the multiprocess application direction: too many IPC was required
for controlling child processes and collecting the monitoring info.
We decided to build a multithreaded application with several worker threads that
serve connections.
9
Multithreading model
The old proxy server used by the customer adopts the thread-per-connection
model.
It doesn't work well when there are more than 30K connections.
So we chose something like the thread-per-core model:
● (nCPU-2) threads allocated for serving connections. We call them io_threads;
● there are also several service threads for working with configuration and so
on.
10
Admin HTTP-entry
One of the service threads is dedicated to handling the admin HTTP-entry point.
That HTTP-entry point is used for accepting a new config and/or new list of
allowed users and their parameters.
That HTTP-entry point is also used for retrieving the current stats from the proxy
server.
11
What's next?
The next part of this presentation tells about the usage of SObjectizer to simplify
multithreading.
Then we'll talk about the usages of RESTinio, some of that could be somewhat
surprising.
12
SObjectizer's related part
Actors instead of raw
multithreading
13
Raw multithreading is a pain
Dealing with raw multithreading in C++ is a straight way to various problems.
We prefer to use more high-level approaches like Actors or CSP.
That is why we developed and maintain SObjectizer that allows us to use Actors
and CSP when we need it.
14
Actors were an obvious choice for aragata
SObjectizer supports Actors and CSP models but in the case of arataga the choice
was clearly obvious.
We have to deal with a large number of independent objects with their own state
and logic.
Those objects required async interaction between each other.
That's an ideal use-case for actors.
15
Types of actors in arataga
There are a few types of actors (agents) in arataga:
● startup_manager;
● config_manager;
● user_list_manager;
● authentificator;
● dns_resolver;
● acl_handler.
16
startup_manager agent
startup_manager is used only at the start up.
It creates config_manager and user_list_manager agents.
Then launches RESTinio-based server for admin HTTP-entry.
17
config_manager agent
Tries to load local copy of the config at the start up.
Handles updates for the config from admin HTTP-entry.
Creates instances of asio_one_thread dispatches, creates and binds
authenificator and dns_resolver agents.
Creates and destroys acl_handler agents.
18
user_list_manager agent
Tries to load local copy of the user-list at the start up.
Handles updates for the user-list from admin HTTP-entry.
Distributes updated versions of user-list to make them available for authentificator
agents.
19
authentificator agent
Services authentification and authorization requests for acl_handler agents.
There is a separate authentificator agent for every io_thread.
20
dns_resolver agent
Services DNS lookup requests for acl_handler agents.
There is a separate dns_resolver*
agent for every io_thread.
21
*
there is no such agent as dns_resolver since v.0.4, now it's a coop of several agents. We'll see that later
acl_handler agent
Services a single entry-point:
● creates an incoming socket for specified IP-address and TCP-port;
● accepts new connections for that entry-point (stops accepting when there are
too many parallel connections);
● handles all accepted connections and all outgoing connection to target hosts.
22
Worker threads
There is no manual work with threads in aragata.
All worker threads required for aragata's agents are automatically created and
destroyed by SObjectizer. It's done by SObjectizer's dispatchers.
23
Dispatchers used in arataga
arataga uses two types of dispatchers:
● one_thread from SObjectizer's core. config_manager and user_list_manager
are bound to instances of that dispatcher type;
● asio_one_thread from so5extra companion project. authentificator,
dns_resolver and acl_handler agents are bound to instances of that
dispatcher type.
24
Agents and dispatchers: the picture
25
What is asio_one_thread dispatcher?
This dispatcher holds an instance of asio::io_context object.
The dispatcher starts a new thread and calls asio::io_context::run on it.
All events of agents bound to that dispatcher are scheduled via asio::post.
That allows agents to use Asio's calls (like async_accept, async_read,
async_write) directly in their event handlers.
This feature is critical for dns_resolver and acl_handler agents.
26
config_manager controls asio_one_thread disps
config_manager creates all necessary instances of asio_one_thread dispatchers
at the start up.
config_manager holds references to them and uses them to bind new instances of
acl_handler agents.
It can be seen as a table inside config_manager where a column describes one
io_thread.
27
config_manager controls asio_one_thread disps
28
config_manager controls acl_handler agents
config_manager creates and destroys acl_handler agents when the config
changes.
29
config_manager controls acl_handler agents
30
The role of acl_handler agent
Services a single entry-point:
● creates an incoming socket for specified IP-address and TCP-port;
● accepts new connections for that entry-point (stops accepting when there are
too many parallel connections);
● reads initial data from accepted connection, detects the client's protocol;
● handles incoming commands from client and establishes outgoing
connections to target hosts;
● transfers data between clients and target hosts.
31
We had plenty of choices:
1. An agent that serves a group of entry points with all related connections.
2. An agent that serves single entry point and all related connections.
3. An agent that serves single entry point and an agent that serves a pair of
incoming/outgoing connections.
4. An agent that serves single entry point, an agent for incoming connection, an
agent for outgoing connection.
5. An agent that serves a group of entry points, an agent for incoming
connection, an agent for outgoing connection.
6. ...
Why an agent for entry point?
32
...that serves also all related connections (incoming to that entry point, and
outgoing from that entry point).
The main reason: simplicity.
It's easy to delete entry point when it is removed from the config.
We decided to have an agent for entry point...
33
Too many agents in an application is not a good thing. It's hard to monitor and
debug program with 40K live agents inside.
Creation and deletion of agents is more expensive operation than creation and
deletion of more lightweight objects that we call connection_handler.
So in arataga an acl_handler agent owns many connection_handler objects.
An instance of connection_handler owns a pair of in/out connections.
connection_handler is created when acl_handler accepts new connection and is
destroyed when that connection is being closed.
No separate agents for in/out connections
34
acl_handler's picture
35
We have a pair of authentificator/dns_resolver agents on every io_thread.
It's an attempt to improve locality.
An acl_handler agent on an io_thread interacts only with authentificator and
dns_resolver agents from the same io_thread.
There is no need to exchange any data between io_threads to serve client
requests.
Why there are several authentificator/dns_resolvers?
36
config_manager handles updated configs and distributes new info to all interested
agents (acl_handlers, authentificators, dns_resolvers).
user_list_manager handles updated user-list and distributes new info to all
authentificator agents.
That distribution is performed by SObjectizer's many-producer/many-consumer
message box.
Distribution of updated configs/user-lists
37
config_managers sends updates to config_updates_mbox and those updates are
received by all subscribers of that mbox:
Config updates distribution scheme
38
retained_mbox is used for config updates
A special kind of message box is used as config_updates_mbox: retained_mbox
from the so5extra companion project.
That type of mbox holds a copy of the last message sent.
When a new subscriber arrives, that last copy is being automatically sent to it.
That way, new acl_handler agents automatically get the latest configuration.
39
dns_resolver is a coop of several agents
We rewrote interaction with DNS name servers in v.0.4 and since then there are
several agents that play the role of dns_resolver.
All other agents in arataga didn't see that change because all interactions are
done via separate interface mbox.
40
The old scheme of dns_resolver's internals
41
acl_handlers know only interface mbox
All acl_handler-agents know only the interface mbox of dns_resolver part.
No one knows what's behind that mbox.
That allowed us to replace a_dns_resolver with a couple of new agents:
● a_collector that collects incoming resolve requests, queues them, holds the
results cache;
● a_nameserver_interactor that performs actual interaction with name servers
using UDP protocol.
No changes were made for acl_handler during that refactoring.
42
Simplified new scheme of dns_resolver's internals
43
There are two a_collector actually...
Actually, every dns_resolver part holds two a_collector agents.
One handles requests for IPv4 addresses, another for IPv6.
But they are subscribed to a single source of resolve_request_t messages.
The separation of incoming message flows is done via SObjectizer's delivery
filters.
44
Actual new scheme of dns_resolver's internals
45
RESTinio's related part
How RESTinio is used in
arataga?
46
RESTinio in arataga: three use cases
We'll see three use cases for RESTinio in arataga.
One is obvious.
The second is not so.
The last is very surprised even for us.
47
An obvious use case: admin HTTP-entry
Admin HTTP-entry in arataga is implemented via RESTinio.
This entry-point accepts and handles GET and POST requests.
Every request should have a special Arataga-Admin-Token header field.
48
Admin HTTP-entry: launching
An instance of RESTinio server is launched by using restinio::run_async...
49
Admin HTTP-entry: launching
struct server_traits_t : public restinio::default_traits_t
{
// There are only three handlers in the chain:
// - checks for admin-token;
// - checks for content-type for POST-requests;
// - actual handling.
using request_handler_t = restinio::sync_chain::fixed_size_chain_t< 3>;
};
50
Admin HTTP-entry: launching
[[nodiscard]] running_entry_handle_t start_entry(
asio::ip::address entry_ip, std::
uint16_t entry_port,
std::string admin_token, requests_mailbox_t & mailbox )
{
auto processor = std::make_shared< impl::request_processor_t >( mailbox );
auto server = restinio::run_async(
restinio::own_io_context(),
restinio::server_settings_t< impl::server_traits_t >{}
.address( entry_ip )
.port( entry_port )
.request_handler(
impl::make_admin_token_checker( std::move(admin_token) ),
impl::make_content_type_checker(),
[handler = std::move(processor)](auto req ) {
return handler->on_request( std::move(req) );
} ),
1 ); // Just one worker thread.
return std::make_unique< impl::actual_running_entry_instance_t >( std::move(server) );
}
51
Admin HTTP-entry: interaction with agents
RESTinio server doesn't know about agents.
Agents don't know about RESTinio.
Interaction is performed via two special interfaces...
52
Admin HTTP-entry: interaction with agents
class replier_t {
public:
virtual ~replier_t();
virtual void reply( status_t status, std::string body ) = 0;
};
53
Admin HTTP-entry: interaction with agents
class requests_mailbox_t {
public:
virtual ~requests_mailbox_t();
virtual void new_config( replier_shptr_t replier, std::string_view content ) = 0;
virtual void
get_acl_list( replier_shptr_t replier ) = 0;
virtual void new_user_list( replier_shptr_t replier, std::string_view content ) = 0;
virtual void get_current_stats( replier_shptr_t replier ) = 0;
...
};
54
Admin HTTP-entry: interaction with agents
RESTinio's part has an actual implementation of replier_t interface.
SObjectizer's part has an actual implementation of request_mailbox_t interface.
55
Admin HTTP-entry: interaction with agents
When HTTP-entry accepts a new request it creates an instance of replier_t and
calls appropriate request_mailbox_t's method.
For example, when a new config is received the new_config() method is called.
The actual implementation of new_config() send a message to the
config_processor agent.
The config_processor handles new config and calls replier_t::reply() method.
56
Admin HTTP-entry: interaction with agents
57
Not obvious, but expected use case: HTTP-headers
We didn't plan to use RESTinio for serving incoming HTTP connections.
It's because the current version of RESTinio loads the whole request into the
memory and only then allows to handle the request.
That approach can't be used in proxy where a lot of large incoming requests have
to be handled without affecting the performance and resource usage.
But we hoped that some parts of RESTinio could simplify our work...
58
Not obvious, but expected use case: HTTP-headers
RESTinio has tools for working with HTTP header fields.
Those tools were reused in arataga.
59
Not obvious, but expected use case: HTTP-headers
RESTinio's http_header_fields_t container is used for holding headers:
struct request_info_t
{
//! HTTP-method of the request.
/*!
* It is stored here to be easily accessible.
*/
http_method m_method;
//! The value of request-target from the start-line.
std::string m_request_target;
//! Extracted HTTP header fields from the incoming request.
restinio::http_header_fields_t m_headers;
...
60
Not obvious, but expected use case: HTTP-headers
Not only for holding headers, but also for handling them:
// If there are more than one Host header fields then the request
// should be rejected. So count the fields.
std::optional< std::string_view > opt_host;
std::size_t host_occurrences{ 0u };
m_request_info. m_headers.for_each_value_of(
restinio::http_field_t::host,
[&]( std::string_view value )
{
++host_occurrences;
if( 1u == host_occurrences ) { opt_host = value; }
return restinio::http_header_fields_t::continue_enumeration();
} );
61
Not obvious, but expected use case: HTTP-headers
RESTinio's http_field_parsers are used for parsing headers:
#include <restinio/helpers/http_field_parsers/authorization.hpp>
#include <restinio/helpers/http_field_parsers/basic_auth.hpp>
...
using namespace restinio::http_field_parsers;
const auto auth_value_result = authorization_value_t::try_parse( *opt_proxy_auth_value );
if( !auth_value_result )
return username_password_extraction_failure_t{
make_error_description( auth_value_result.error(), *opt_proxy_auth_value )
};
...
auto basic_auth_result = basic_auth::try_extract_params( auth_value );
if( !basic_auth_result )
return username_password_extraction_failure_t{
fmt::format( "basic-auth param extraction failed: {}" ,
static_cast<int>(basic_auth_result.error()) )
};
62
Totally unexpected use case: config parsing
We have to parse a couple of config files with custom syntax.
That syntax wasn't too complex in general, but the standard C++ library totally
lacks any useful tools for such a task :(
Moreover, we wanted to make the syntax more user-friendly. For example, we
wanted to have an ability to write like that:
acl.io.chunk_size 16kib # Instead of 16384
timeout.authentification 12s # Instead of 12000
dns_cache_cleanup_period 6min # Instead of 360
63
Totally unexpected use case: config parsing
We solved that task by using RESTinio's easy_parser that is used in RESTinio for
parsing HTTP header fields.
As an example we'll show how values like 1min, or 25s, or 125ms are parsed...
64
An example of RESTinio-based parser (1)
Factory for parsers of time-out values:
/*!
* @brief A producer for easy_parser that extracts time-out values
* with possible suffixes (ms, s, min).
*/
[[nodiscard]] static auto timeout_value_p()
{
struct tmp_value_t
{
std:: int_least64_t m_count{ 0 };
int m_multiplier{ 1000 };
};
using namespace restinio::http_field_parsers;
using std::chrono::milliseconds;
65
An example of RESTinio-based parser (2)
return produce< milliseconds >(
produce< tmp_value_t >(
non_negative_decimal_number_p< std:: int_least64_t >() >> &tmp_value_t::m_count,
maybe(
produce< int >(
alternatives(
exact_p( "min" ) >> just_result( 60'000 ),
exact_p( "s" ) >> just_result( 1'000 ),
exact_p( "ms" ) >> just_result( 1 )
)
) >> &tmp_value_t::m_multiplier
)
)
>> convert( []( const auto tmp ) { return milliseconds{tmp.m_count} * tmp.m_multiplier; } )
>> as_result()
);
}
66
An example of RESTinio-based parser (3)
A usage of that parser:
//! Handler for `dns_cache_cleanup_period` command.
class dns_cache_cleanup_period_handler_t : public command_handler_t
{
public:
command_handling_result_t try_handle(
std::string_view content, config_t & current_cfg ) const override
{
return perform_parsing( content, parsers::timeout_value_p(),
[&]( std::chrono::milliseconds v ) -> command_handling_result_t {
if( std::chrono::milliseconds::zero() == v )
return failure_t{ "dns_cache_cleanup_period can't be 0" };
current_cfg.m_dns_cache_cleanup_period = v;
return success_t{};
} );
}
};
67
Epilog
68
Unfortunately, arataga wasn't stress-tested enough
Because the customer lost interest in the project, the arataga wasn't stress-tested
under the huge loads.
Only a few stress tests were performed.
In config and load dependency, arataga used from 1.5 to 4 times less CPU
consumption than the customer's old proxy server under the same workload.
69
The current status
The active development of arataga was suspended in 2020.
We ourselves consider arataga to be an excellent testing ground for the
approbation of new versions of SObjectizer and RESTinio in real-life conditions.
So we make some changes to arataga from time to time when we have some new
idea.
We also fix issues when someone reports them. If you find a problem in arataga
feel free to open an issue on GitHub.
70
Our own impressions: RESTinio
71
The use of RESTinio in arataga gave us some ideas for new RESTinio's features.
One of them, chain of synchronous handlers, was implemented and available
since RESTinio-0.6.13.
Others still wait their time...
Our own impressions: SObjectizer
Usual routine, nothing exciting, no challenges.
We took SObjectizer, wrote several agents, and that's all.
SObjectizer just works. There weren't any SObjectizer's or multithreading-related
issues.
72
References
https://github.com/Stiffstream/arataga
https://github.com/Stiffstream/sobjectizer
https://github.com/Stiffstream/so5extra
https://github.com/Stiffstream/restinio
73
That's all
Thanks!
74

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. Exception
Yauheni Akhotnikau
 
Dive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable MessagesDive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable Messages
Yauheni Akhotnikau
 
Parallel Programming With Dot Net
Parallel Programming With Dot NetParallel Programming With Dot Net
Parallel Programming With Dot Net
Neeraj Kaushik
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
sheibansari
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMS
PVS-Studio
 
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
Katy Slemon
 
Date Processing Attracts Bugs or 77 Defects in Qt 6
Date Processing Attracts Bugs or 77 Defects in Qt 6Date Processing Attracts Bugs or 77 Defects in Qt 6
Date Processing Attracts Bugs or 77 Defects in Qt 6
Andrey Karpov
 
Angular2 + rxjs
Angular2 + rxjsAngular2 + rxjs
Angular2 + rxjs
Christoffer Noring
 
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
Micha Kops
 
Kubernetes
KubernetesKubernetes
Kubernetes
Lhouceine OUHAMZA
 
CDI: How do I ?
CDI: How do I ?CDI: How do I ?
CDI: How do I ?
Antonio Goncalves
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroid
Savvycom Savvycom
 
Complete Java Course
Complete Java CourseComplete Java Course
Complete Java Course
Lhouceine OUHAMZA
 
The Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFuturesThe Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFutures
Haim Yadid
 
Javascript internals
Javascript internalsJavascript internals
Javascript internals
Nir Noy
 
Overview of Node JS
Overview of Node JSOverview of Node JS
Overview of Node JS
Jacob Nelson
 
Java7
Java7Java7
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results Asynchrhonously
David Gómez García
 
Completable future
Completable futureCompletable future
Completable future
Srinivasan Raghvan
 
SERVIET
SERVIETSERVIET
SERVIET
sathish sak
 

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
 
Dive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable MessagesDive into SObjectizer 5.5. Tenth part: Mutable Messages
Dive into SObjectizer 5.5. Tenth part: Mutable Messages
 
Parallel Programming With Dot Net
Parallel Programming With Dot NetParallel Programming With Dot Net
Parallel Programming With Dot Net
 
C++aptitude questions and answers
C++aptitude questions and answersC++aptitude questions and answers
C++aptitude questions and answers
 
Analysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMSAnalysis of bugs in Orchard CMS
Analysis of bugs in Orchard CMS
 
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
 
Date Processing Attracts Bugs or 77 Defects in Qt 6
Date Processing Attracts Bugs or 77 Defects in Qt 6Date Processing Attracts Bugs or 77 Defects in Qt 6
Date Processing Attracts Bugs or 77 Defects in Qt 6
 
Angular2 + rxjs
Angular2 + rxjsAngular2 + rxjs
Angular2 + rxjs
 
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
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
CDI: How do I ?
CDI: How do I ?CDI: How do I ?
CDI: How do I ?
 
Reactive programming with RxAndroid
Reactive programming with RxAndroidReactive programming with RxAndroid
Reactive programming with RxAndroid
 
Complete Java Course
Complete Java CourseComplete Java Course
Complete Java Course
 
The Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFuturesThe Future of Futures - A Talk About Java 8 CompletableFutures
The Future of Futures - A Talk About Java 8 CompletableFutures
 
Javascript internals
Javascript internalsJavascript internals
Javascript internals
 
Overview of Node JS
Overview of Node JSOverview of Node JS
Overview of Node JS
 
Java7
Java7Java7
Java7
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results Asynchrhonously
 
Completable future
Completable futureCompletable future
Completable future
 
SERVIET
SERVIETSERVIET
SERVIET
 

Similar to arataga. SObjectizer and RESTinio in action: a real-world example

OCP with super tengen toppa
OCP with super tengen toppaOCP with super tengen toppa
OCP with super tengen toppa
hyeongchae lee
 
MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2
MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2
MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2
Alfonso Martino
 
Docker Voting App Orientation
Docker Voting App OrientationDocker Voting App Orientation
Docker Voting App Orientation
Tony Pujals
 
.NET Core Apps: Design & Development
.NET Core Apps: Design & Development.NET Core Apps: Design & Development
.NET Core Apps: Design & Development
GlobalLogic Ukraine
 
Cloudfoundry Introduction
Cloudfoundry IntroductionCloudfoundry Introduction
Cloudfoundry Introduction
Yitao Jiang
 
Ultimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on KubernetesUltimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on Kubernetes
kloia
 
Network Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage Service
Network Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage ServiceNetwork Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage Service
Network Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage Service
Cloudian
 
Alteryx Architecture
Alteryx ArchitectureAlteryx Architecture
Alteryx Architecture
Vivek Mohan
 
Alteryx Architecture
Alteryx ArchitectureAlteryx Architecture
Alteryx Architecture
Vivek Mohan
 
ASP.NET Core and Docker
ASP.NET Core and DockerASP.NET Core and Docker
ASP.NET Core and Docker
Chuck Megivern
 
KrakenD API Gateway
KrakenD API GatewayKrakenD API Gateway
KrakenD API Gateway
Albert Lombarte
 
Pandora FMS: Outlook Anywhere Plugin
Pandora FMS: Outlook Anywhere PluginPandora FMS: Outlook Anywhere Plugin
Pandora FMS: Outlook Anywhere Plugin
Pandora FMS
 
Microservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive ProgrammingMicroservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive Programming
Araf Karsh Hamid
 
Kubernetes Architecture with Components
 Kubernetes Architecture with Components Kubernetes Architecture with Components
Kubernetes Architecture with Components
Ajeet Singh
 
Disadvantages Of Robotium
Disadvantages Of RobotiumDisadvantages Of Robotium
Disadvantages Of Robotium
Susan Tullis
 
Introduction to Thrift
Introduction to ThriftIntroduction to Thrift
Introduction to ThriftDvir Volk
 
HAProxy as Egress Controller
HAProxy as Egress ControllerHAProxy as Egress Controller
HAProxy as Egress Controller
Julien Pivotto
 
DevOps Days Boston 2017: Real-world Kubernetes for DevOps
DevOps Days Boston 2017: Real-world Kubernetes for DevOpsDevOps Days Boston 2017: Real-world Kubernetes for DevOps
DevOps Days Boston 2017: Real-world Kubernetes for DevOps
Ambassador Labs
 
Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)
Eran Harel
 
Serverless Design Patterns (London Dev Community)
Serverless Design Patterns (London Dev Community)Serverless Design Patterns (London Dev Community)
Serverless Design Patterns (London Dev Community)
Yan Cui
 

Similar to arataga. SObjectizer and RESTinio in action: a real-world example (20)

OCP with super tengen toppa
OCP with super tengen toppaOCP with super tengen toppa
OCP with super tengen toppa
 
MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2
MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2
MuleSoft Meetup Roma - Runtime Fabric Series (From Zero to Hero) - Sessione 2
 
Docker Voting App Orientation
Docker Voting App OrientationDocker Voting App Orientation
Docker Voting App Orientation
 
.NET Core Apps: Design & Development
.NET Core Apps: Design & Development.NET Core Apps: Design & Development
.NET Core Apps: Design & Development
 
Cloudfoundry Introduction
Cloudfoundry IntroductionCloudfoundry Introduction
Cloudfoundry Introduction
 
Ultimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on KubernetesUltimate Guide to Microservice Architecture on Kubernetes
Ultimate Guide to Microservice Architecture on Kubernetes
 
Network Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage Service
Network Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage ServiceNetwork Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage Service
Network Setup Guide: Deploying Your Cloudian HyperStore Hybrid Storage Service
 
Alteryx Architecture
Alteryx ArchitectureAlteryx Architecture
Alteryx Architecture
 
Alteryx Architecture
Alteryx ArchitectureAlteryx Architecture
Alteryx Architecture
 
ASP.NET Core and Docker
ASP.NET Core and DockerASP.NET Core and Docker
ASP.NET Core and Docker
 
KrakenD API Gateway
KrakenD API GatewayKrakenD API Gateway
KrakenD API Gateway
 
Pandora FMS: Outlook Anywhere Plugin
Pandora FMS: Outlook Anywhere PluginPandora FMS: Outlook Anywhere Plugin
Pandora FMS: Outlook Anywhere Plugin
 
Microservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive ProgrammingMicroservices Part 4: Functional Reactive Programming
Microservices Part 4: Functional Reactive Programming
 
Kubernetes Architecture with Components
 Kubernetes Architecture with Components Kubernetes Architecture with Components
Kubernetes Architecture with Components
 
Disadvantages Of Robotium
Disadvantages Of RobotiumDisadvantages Of Robotium
Disadvantages Of Robotium
 
Introduction to Thrift
Introduction to ThriftIntroduction to Thrift
Introduction to Thrift
 
HAProxy as Egress Controller
HAProxy as Egress ControllerHAProxy as Egress Controller
HAProxy as Egress Controller
 
DevOps Days Boston 2017: Real-world Kubernetes for DevOps
DevOps Days Boston 2017: Real-world Kubernetes for DevOpsDevOps Days Boston 2017: Real-world Kubernetes for DevOps
DevOps Days Boston 2017: Real-world Kubernetes for DevOps
 
Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)Service discovery like a pro (presented at reversimX)
Service discovery like a pro (presented at reversimX)
 
Serverless Design Patterns (London Dev Community)
Serverless Design Patterns (London Dev Community)Serverless Design Patterns (London Dev Community)
Serverless Design Patterns (London Dev Community)
 

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
 
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
 
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
 
[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 Eyes
Yauheni 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 all
Yauheni 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.9
What's new in SObjectizer 5.5.9What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9
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.8
Yauheni Akhotnikau
 
Погружение в SObjectizer 5.5. Вводная часть
Погружение в SObjectizer 5.5. Вводная частьПогружение в SObjectizer 5.5. Вводная часть
Погружение в SObjectizer 5.5. Вводная часть
Yauheni Akhotnikau
 
Обзор SObjectizer 5.5
Обзор SObjectizer 5.5Обзор SObjectizer 5.5
Обзор SObjectizer 5.5
Yauheni Akhotnikau
 

More from Yauheni Akhotnikau (17)

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)
 
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)
 
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)
 
[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.9
What's new in SObjectizer 5.5.9What's new in SObjectizer 5.5.9
What's new in SObjectizer 5.5.9
 
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

Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
Google
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
Aftab Hussain
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
Alina Yurenko
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 

Recently uploaded (20)

Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
AI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website CreatorAI Genie Review: World’s First Open AI WordPress Website Creator
AI Genie Review: World’s First Open AI WordPress Website Creator
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Graspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code AnalysisGraspan: A Big Data System for Big Code Analysis
Graspan: A Big Data System for Big Code Analysis
 
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)GOING AOT WITH GRAALVM FOR  SPRING BOOT (SPRING IO)
GOING AOT WITH GRAALVM FOR SPRING BOOT (SPRING IO)
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 

arataga. SObjectizer and RESTinio in action: a real-world example

  • 1. arataga SObjectizer and RESTinio in action: a real-world example
  • 3. What is 'arataga' arataga is a fully working prototype of performant socks5+http/1.1 proxy server targeted a case when thousands of entry points have to be opened. 3
  • 4. A way to open source arataga was in development in the summer of 2020 by stiffsteam for a customer who wanted to replace its own old proxy server. For some reason, the customer abandoned the project. But almost all functionality we wanted to have was already implemented, so we decided to open source arataga. 4
  • 5. Why we open sourced aragata? It's a shame to throw away a product that our hard work was put into. Maybe the results of our work will be useful for somebody. It's also a perfect showcase of how we write code using SObjectizer and RESTinio. 5
  • 7. Requirements for arataga and design decisions 7
  • 8. Projects requirements ● thousands of entry-points (unique pairs of IP-address+TCP-port). At least 8K entry-points should have been supported at the beginning; ● tens of thousands of users can work with the proxy simultaneously (40K parallel connections is a normal workload); ● user connections/disconnections at the rate of 1,000+ new connections per second; ● bandwidth had to be limited for client connections, including limits for a particular domains; ● the configuration and lists of allowed users must be received via a special HTTP entry point. 8
  • 9. Multithreading or multiprocessing Tens of thousands of connections are expected. They hardly be handled in a single-thread application. We didn't go in the multiprocess application direction: too many IPC was required for controlling child processes and collecting the monitoring info. We decided to build a multithreaded application with several worker threads that serve connections. 9
  • 10. Multithreading model The old proxy server used by the customer adopts the thread-per-connection model. It doesn't work well when there are more than 30K connections. So we chose something like the thread-per-core model: ● (nCPU-2) threads allocated for serving connections. We call them io_threads; ● there are also several service threads for working with configuration and so on. 10
  • 11. Admin HTTP-entry One of the service threads is dedicated to handling the admin HTTP-entry point. That HTTP-entry point is used for accepting a new config and/or new list of allowed users and their parameters. That HTTP-entry point is also used for retrieving the current stats from the proxy server. 11
  • 12. What's next? The next part of this presentation tells about the usage of SObjectizer to simplify multithreading. Then we'll talk about the usages of RESTinio, some of that could be somewhat surprising. 12
  • 13. SObjectizer's related part Actors instead of raw multithreading 13
  • 14. Raw multithreading is a pain Dealing with raw multithreading in C++ is a straight way to various problems. We prefer to use more high-level approaches like Actors or CSP. That is why we developed and maintain SObjectizer that allows us to use Actors and CSP when we need it. 14
  • 15. Actors were an obvious choice for aragata SObjectizer supports Actors and CSP models but in the case of arataga the choice was clearly obvious. We have to deal with a large number of independent objects with their own state and logic. Those objects required async interaction between each other. That's an ideal use-case for actors. 15
  • 16. Types of actors in arataga There are a few types of actors (agents) in arataga: ● startup_manager; ● config_manager; ● user_list_manager; ● authentificator; ● dns_resolver; ● acl_handler. 16
  • 17. startup_manager agent startup_manager is used only at the start up. It creates config_manager and user_list_manager agents. Then launches RESTinio-based server for admin HTTP-entry. 17
  • 18. config_manager agent Tries to load local copy of the config at the start up. Handles updates for the config from admin HTTP-entry. Creates instances of asio_one_thread dispatches, creates and binds authenificator and dns_resolver agents. Creates and destroys acl_handler agents. 18
  • 19. user_list_manager agent Tries to load local copy of the user-list at the start up. Handles updates for the user-list from admin HTTP-entry. Distributes updated versions of user-list to make them available for authentificator agents. 19
  • 20. authentificator agent Services authentification and authorization requests for acl_handler agents. There is a separate authentificator agent for every io_thread. 20
  • 21. dns_resolver agent Services DNS lookup requests for acl_handler agents. There is a separate dns_resolver* agent for every io_thread. 21 * there is no such agent as dns_resolver since v.0.4, now it's a coop of several agents. We'll see that later
  • 22. acl_handler agent Services a single entry-point: ● creates an incoming socket for specified IP-address and TCP-port; ● accepts new connections for that entry-point (stops accepting when there are too many parallel connections); ● handles all accepted connections and all outgoing connection to target hosts. 22
  • 23. Worker threads There is no manual work with threads in aragata. All worker threads required for aragata's agents are automatically created and destroyed by SObjectizer. It's done by SObjectizer's dispatchers. 23
  • 24. Dispatchers used in arataga arataga uses two types of dispatchers: ● one_thread from SObjectizer's core. config_manager and user_list_manager are bound to instances of that dispatcher type; ● asio_one_thread from so5extra companion project. authentificator, dns_resolver and acl_handler agents are bound to instances of that dispatcher type. 24
  • 25. Agents and dispatchers: the picture 25
  • 26. What is asio_one_thread dispatcher? This dispatcher holds an instance of asio::io_context object. The dispatcher starts a new thread and calls asio::io_context::run on it. All events of agents bound to that dispatcher are scheduled via asio::post. That allows agents to use Asio's calls (like async_accept, async_read, async_write) directly in their event handlers. This feature is critical for dns_resolver and acl_handler agents. 26
  • 27. config_manager controls asio_one_thread disps config_manager creates all necessary instances of asio_one_thread dispatchers at the start up. config_manager holds references to them and uses them to bind new instances of acl_handler agents. It can be seen as a table inside config_manager where a column describes one io_thread. 27
  • 29. config_manager controls acl_handler agents config_manager creates and destroys acl_handler agents when the config changes. 29
  • 31. The role of acl_handler agent Services a single entry-point: ● creates an incoming socket for specified IP-address and TCP-port; ● accepts new connections for that entry-point (stops accepting when there are too many parallel connections); ● reads initial data from accepted connection, detects the client's protocol; ● handles incoming commands from client and establishes outgoing connections to target hosts; ● transfers data between clients and target hosts. 31
  • 32. We had plenty of choices: 1. An agent that serves a group of entry points with all related connections. 2. An agent that serves single entry point and all related connections. 3. An agent that serves single entry point and an agent that serves a pair of incoming/outgoing connections. 4. An agent that serves single entry point, an agent for incoming connection, an agent for outgoing connection. 5. An agent that serves a group of entry points, an agent for incoming connection, an agent for outgoing connection. 6. ... Why an agent for entry point? 32
  • 33. ...that serves also all related connections (incoming to that entry point, and outgoing from that entry point). The main reason: simplicity. It's easy to delete entry point when it is removed from the config. We decided to have an agent for entry point... 33
  • 34. Too many agents in an application is not a good thing. It's hard to monitor and debug program with 40K live agents inside. Creation and deletion of agents is more expensive operation than creation and deletion of more lightweight objects that we call connection_handler. So in arataga an acl_handler agent owns many connection_handler objects. An instance of connection_handler owns a pair of in/out connections. connection_handler is created when acl_handler accepts new connection and is destroyed when that connection is being closed. No separate agents for in/out connections 34
  • 36. We have a pair of authentificator/dns_resolver agents on every io_thread. It's an attempt to improve locality. An acl_handler agent on an io_thread interacts only with authentificator and dns_resolver agents from the same io_thread. There is no need to exchange any data between io_threads to serve client requests. Why there are several authentificator/dns_resolvers? 36
  • 37. config_manager handles updated configs and distributes new info to all interested agents (acl_handlers, authentificators, dns_resolvers). user_list_manager handles updated user-list and distributes new info to all authentificator agents. That distribution is performed by SObjectizer's many-producer/many-consumer message box. Distribution of updated configs/user-lists 37
  • 38. config_managers sends updates to config_updates_mbox and those updates are received by all subscribers of that mbox: Config updates distribution scheme 38
  • 39. retained_mbox is used for config updates A special kind of message box is used as config_updates_mbox: retained_mbox from the so5extra companion project. That type of mbox holds a copy of the last message sent. When a new subscriber arrives, that last copy is being automatically sent to it. That way, new acl_handler agents automatically get the latest configuration. 39
  • 40. dns_resolver is a coop of several agents We rewrote interaction with DNS name servers in v.0.4 and since then there are several agents that play the role of dns_resolver. All other agents in arataga didn't see that change because all interactions are done via separate interface mbox. 40
  • 41. The old scheme of dns_resolver's internals 41
  • 42. acl_handlers know only interface mbox All acl_handler-agents know only the interface mbox of dns_resolver part. No one knows what's behind that mbox. That allowed us to replace a_dns_resolver with a couple of new agents: ● a_collector that collects incoming resolve requests, queues them, holds the results cache; ● a_nameserver_interactor that performs actual interaction with name servers using UDP protocol. No changes were made for acl_handler during that refactoring. 42
  • 43. Simplified new scheme of dns_resolver's internals 43
  • 44. There are two a_collector actually... Actually, every dns_resolver part holds two a_collector agents. One handles requests for IPv4 addresses, another for IPv6. But they are subscribed to a single source of resolve_request_t messages. The separation of incoming message flows is done via SObjectizer's delivery filters. 44
  • 45. Actual new scheme of dns_resolver's internals 45
  • 46. RESTinio's related part How RESTinio is used in arataga? 46
  • 47. RESTinio in arataga: three use cases We'll see three use cases for RESTinio in arataga. One is obvious. The second is not so. The last is very surprised even for us. 47
  • 48. An obvious use case: admin HTTP-entry Admin HTTP-entry in arataga is implemented via RESTinio. This entry-point accepts and handles GET and POST requests. Every request should have a special Arataga-Admin-Token header field. 48
  • 49. Admin HTTP-entry: launching An instance of RESTinio server is launched by using restinio::run_async... 49
  • 50. Admin HTTP-entry: launching struct server_traits_t : public restinio::default_traits_t { // There are only three handlers in the chain: // - checks for admin-token; // - checks for content-type for POST-requests; // - actual handling. using request_handler_t = restinio::sync_chain::fixed_size_chain_t< 3>; }; 50
  • 51. Admin HTTP-entry: launching [[nodiscard]] running_entry_handle_t start_entry( asio::ip::address entry_ip, std:: uint16_t entry_port, std::string admin_token, requests_mailbox_t & mailbox ) { auto processor = std::make_shared< impl::request_processor_t >( mailbox ); auto server = restinio::run_async( restinio::own_io_context(), restinio::server_settings_t< impl::server_traits_t >{} .address( entry_ip ) .port( entry_port ) .request_handler( impl::make_admin_token_checker( std::move(admin_token) ), impl::make_content_type_checker(), [handler = std::move(processor)](auto req ) { return handler->on_request( std::move(req) ); } ), 1 ); // Just one worker thread. return std::make_unique< impl::actual_running_entry_instance_t >( std::move(server) ); } 51
  • 52. Admin HTTP-entry: interaction with agents RESTinio server doesn't know about agents. Agents don't know about RESTinio. Interaction is performed via two special interfaces... 52
  • 53. Admin HTTP-entry: interaction with agents class replier_t { public: virtual ~replier_t(); virtual void reply( status_t status, std::string body ) = 0; }; 53
  • 54. Admin HTTP-entry: interaction with agents class requests_mailbox_t { public: virtual ~requests_mailbox_t(); virtual void new_config( replier_shptr_t replier, std::string_view content ) = 0; virtual void get_acl_list( replier_shptr_t replier ) = 0; virtual void new_user_list( replier_shptr_t replier, std::string_view content ) = 0; virtual void get_current_stats( replier_shptr_t replier ) = 0; ... }; 54
  • 55. Admin HTTP-entry: interaction with agents RESTinio's part has an actual implementation of replier_t interface. SObjectizer's part has an actual implementation of request_mailbox_t interface. 55
  • 56. Admin HTTP-entry: interaction with agents When HTTP-entry accepts a new request it creates an instance of replier_t and calls appropriate request_mailbox_t's method. For example, when a new config is received the new_config() method is called. The actual implementation of new_config() send a message to the config_processor agent. The config_processor handles new config and calls replier_t::reply() method. 56
  • 58. Not obvious, but expected use case: HTTP-headers We didn't plan to use RESTinio for serving incoming HTTP connections. It's because the current version of RESTinio loads the whole request into the memory and only then allows to handle the request. That approach can't be used in proxy where a lot of large incoming requests have to be handled without affecting the performance and resource usage. But we hoped that some parts of RESTinio could simplify our work... 58
  • 59. Not obvious, but expected use case: HTTP-headers RESTinio has tools for working with HTTP header fields. Those tools were reused in arataga. 59
  • 60. Not obvious, but expected use case: HTTP-headers RESTinio's http_header_fields_t container is used for holding headers: struct request_info_t { //! HTTP-method of the request. /*! * It is stored here to be easily accessible. */ http_method m_method; //! The value of request-target from the start-line. std::string m_request_target; //! Extracted HTTP header fields from the incoming request. restinio::http_header_fields_t m_headers; ... 60
  • 61. Not obvious, but expected use case: HTTP-headers Not only for holding headers, but also for handling them: // If there are more than one Host header fields then the request // should be rejected. So count the fields. std::optional< std::string_view > opt_host; std::size_t host_occurrences{ 0u }; m_request_info. m_headers.for_each_value_of( restinio::http_field_t::host, [&]( std::string_view value ) { ++host_occurrences; if( 1u == host_occurrences ) { opt_host = value; } return restinio::http_header_fields_t::continue_enumeration(); } ); 61
  • 62. Not obvious, but expected use case: HTTP-headers RESTinio's http_field_parsers are used for parsing headers: #include <restinio/helpers/http_field_parsers/authorization.hpp> #include <restinio/helpers/http_field_parsers/basic_auth.hpp> ... using namespace restinio::http_field_parsers; const auto auth_value_result = authorization_value_t::try_parse( *opt_proxy_auth_value ); if( !auth_value_result ) return username_password_extraction_failure_t{ make_error_description( auth_value_result.error(), *opt_proxy_auth_value ) }; ... auto basic_auth_result = basic_auth::try_extract_params( auth_value ); if( !basic_auth_result ) return username_password_extraction_failure_t{ fmt::format( "basic-auth param extraction failed: {}" , static_cast<int>(basic_auth_result.error()) ) }; 62
  • 63. Totally unexpected use case: config parsing We have to parse a couple of config files with custom syntax. That syntax wasn't too complex in general, but the standard C++ library totally lacks any useful tools for such a task :( Moreover, we wanted to make the syntax more user-friendly. For example, we wanted to have an ability to write like that: acl.io.chunk_size 16kib # Instead of 16384 timeout.authentification 12s # Instead of 12000 dns_cache_cleanup_period 6min # Instead of 360 63
  • 64. Totally unexpected use case: config parsing We solved that task by using RESTinio's easy_parser that is used in RESTinio for parsing HTTP header fields. As an example we'll show how values like 1min, or 25s, or 125ms are parsed... 64
  • 65. An example of RESTinio-based parser (1) Factory for parsers of time-out values: /*! * @brief A producer for easy_parser that extracts time-out values * with possible suffixes (ms, s, min). */ [[nodiscard]] static auto timeout_value_p() { struct tmp_value_t { std:: int_least64_t m_count{ 0 }; int m_multiplier{ 1000 }; }; using namespace restinio::http_field_parsers; using std::chrono::milliseconds; 65
  • 66. An example of RESTinio-based parser (2) return produce< milliseconds >( produce< tmp_value_t >( non_negative_decimal_number_p< std:: int_least64_t >() >> &tmp_value_t::m_count, maybe( produce< int >( alternatives( exact_p( "min" ) >> just_result( 60'000 ), exact_p( "s" ) >> just_result( 1'000 ), exact_p( "ms" ) >> just_result( 1 ) ) ) >> &tmp_value_t::m_multiplier ) ) >> convert( []( const auto tmp ) { return milliseconds{tmp.m_count} * tmp.m_multiplier; } ) >> as_result() ); } 66
  • 67. An example of RESTinio-based parser (3) A usage of that parser: //! Handler for `dns_cache_cleanup_period` command. class dns_cache_cleanup_period_handler_t : public command_handler_t { public: command_handling_result_t try_handle( std::string_view content, config_t & current_cfg ) const override { return perform_parsing( content, parsers::timeout_value_p(), [&]( std::chrono::milliseconds v ) -> command_handling_result_t { if( std::chrono::milliseconds::zero() == v ) return failure_t{ "dns_cache_cleanup_period can't be 0" }; current_cfg.m_dns_cache_cleanup_period = v; return success_t{}; } ); } }; 67
  • 69. Unfortunately, arataga wasn't stress-tested enough Because the customer lost interest in the project, the arataga wasn't stress-tested under the huge loads. Only a few stress tests were performed. In config and load dependency, arataga used from 1.5 to 4 times less CPU consumption than the customer's old proxy server under the same workload. 69
  • 70. The current status The active development of arataga was suspended in 2020. We ourselves consider arataga to be an excellent testing ground for the approbation of new versions of SObjectizer and RESTinio in real-life conditions. So we make some changes to arataga from time to time when we have some new idea. We also fix issues when someone reports them. If you find a problem in arataga feel free to open an issue on GitHub. 70
  • 71. Our own impressions: RESTinio 71 The use of RESTinio in arataga gave us some ideas for new RESTinio's features. One of them, chain of synchronous handlers, was implemented and available since RESTinio-0.6.13. Others still wait their time...
  • 72. Our own impressions: SObjectizer Usual routine, nothing exciting, no challenges. We took SObjectizer, wrote several agents, and that's all. SObjectizer just works. There weren't any SObjectizer's or multithreading-related issues. 72