SlideShare a Scribd company logo
Shrimp: A Rather Practical Example Of Application Development With RESTinio and SObjectizer
A few words about us
●
●
2
A starting point
3
What is Shrimp? From 30000 feets
4

Recommended for you

Forgive me for i have allocated
Forgive me for i have allocatedForgive me for i have allocated
Forgive me for i have allocated

You probably know the mantra that allocation is cheap. It usually is true, but devil is in the details. In your use case object allocation may impact processor caches evicting important data; burn CPU on executing constructor code; impact rates of object promotion to old generation and most importantly increase frequency of stop the word young gen pauses. This presentation is for you if you are working on a Java based services that need to handle more and more traffic. As number of transactions per second rises you might hit performance wall that are young generation gc stopping whole application for precious milliseconds. This presentation focuses on optimising object creation rate when dealing with seemingly mundane tasks. I will show few examples of surprising places in JDK and other libraries where garbage is created. I will explain how New Gen GC collection works and what costs are related to it. We will se escape analysis in action. Finally we will conclude that controlling allocation is the concern of library writers so that we can easily implement performant code without doing premature optimisations.

gcgarbage collectionmechanical sympathy
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js

This talk was given at JSSummit 2013. Entitled "Avoiding Callback Hell with Async.js", my talk focused on common pitfalls with asynchronous functions and callbacks in JavaScript, and using the async.js library and its advanced control flows to create cleaner, more manageable code.

node.jsnodejavascript
Behind modern concurrency primitives
Behind modern concurrency primitivesBehind modern concurrency primitives
Behind modern concurrency primitives

The document discusses modern concurrency primitives like threads, thread pools, coroutines, and schedulers. It covers why asynchronous programming with async/await is preferred over traditional threading. It also discusses challenges like sharing data across threads and blocking on I/O calls. Some solutions covered include using thread pools with dedicated I/O threads, work stealing, and introducing interruption points in long-running tasks.

Why Shrimp was created?
●
●
●
5
But there is another reason
6
We need to go deeper...
7
What is Shrimp? Actually
●
●
8

Recommended for you

Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams

This document provides an introduction to Akka.NET Streams and Reactive Streams. It discusses key concepts like observables, async enumerables, and reactive streams. It also demonstrates how to build workflows with Akka.NET streams, including examples of building a TCP server. The document introduces core Akka.NET streams concepts like sources, flows, and sinks, and how they compose together in a runnable graph. It also covers testing streams with probes and materialization.

akka.netreactive streams
Callbacks and control flow in Node js
Callbacks and control flow in Node jsCallbacks and control flow in Node js
Callbacks and control flow in Node js

A few slides about asynchrnous programming in Node, from callback hell to control flows using promises, thunks and generators, providing the right amount of abstraction to write great code. All examples available on https://github.com/troch/node-control-flow.

iteratorsthunkifycallback
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...

The document discusses dependency injection and inversion of control principles in PHP applications. It provides examples of using global variables, Zend Registry, and Zend Application to manage dependencies. It also summarizes various PHP dependency injection containers and how they can be used to configure services and their dependencies. The document advocates designing applications with loose coupling, separation of concerns, and configuring via configuration files rather than code for improved maintainability.

zfconf2010dependency injectionzfconf
Shrimp in a simple example
9
Shrimp in a simple example
10
$ curl -o test.webp 
"https://shrimp-demo.stiffstream.com/DSCF6555.jpg?op=resize&width=300&target-format=webp"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 41162 100 41162 0 0 41162 0 0:00:01 --:--:-- 0:00:01 151k
$ ls -l *.webp
-rw-rw-r-- 1 eao197 eao197 41162 сен 4 08:28 test.webp
Shrimp in a simple example
11
$ curl -o test.webp 
"https://shrimp-demo.stiffstream.com/DSCF6555.jpg?op=resize&width=300&target-format=webp"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 41162 100 41162 0 0 41162 0 0:00:01 --:--:-- 0:00:01 151k
$ ls -l *.webp
-rw-rw-r-- 1 eao197 eao197 41162 сен 4 08:28 test.webp
More formal description
/<file-name>[?params]
●
●
●
12

Recommended for you

Beyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js TransactionsBeyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js Transactions

Node.js is fast, but once the code is in production, how can you make sure it's still fast? In this talk from the Boston node.js meetup on October 9th, I talk about various strategies for monitoring node in production, with an obvious bias towards transaction tracing.

monitoringnode.jsperformance
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

Slides from my tutorial on creating a websocket chat application using Java EE 7, GlassFish4, Maven, Bootstrap and jQuery.

chatbootstrapjavaee
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8

If you thought Monads are a mystery, then this demonstration would show you how to evolve your code towards a Monad without knowing about it. This demo will neither go into any Category Theory nor begin with monadic laws. Instead, we will start with typical code that you see in your daily life as a developer, attempt to DRY (Don't Repeat Yourself) it up and eventually use Monad to remove duplication and verbosity. You'll also see how Monads make your code more declarative and succinct by sequencing the steps in your domain logic. Also, we know in Java8 Checked Exceptions + λ == Pain! To be more precise, we will evolve a Try&lt;t> (exception handling monad) which is missing in Java8, similar to one found in Scala.

monadsfunctional programming
Examples
/DSCF6555.jpg
/DSCF6555.jpg?target-format=heic
/DSCF6555.jpg?op=resize&max=1024
/DSCF6555.jpg?op=resize&max=1024&target-format=heic
13
Live demo
14
Project's sources
15
Disclaimer
16

Recommended for you

Finatra v2
Finatra v2Finatra v2
Finatra v2

Finatra v2 is a framework for building Scala HTTP and Thrift services on Twitter's stack. It started as an internal project at Twitter in 2012 and was publicly released in 2015. Version 2.0 is 50x faster than 1.6 in benchmarks and includes features like dependency injection, JSON parsing, logging and request scoping. The document provides a tutorial demonstrating how to build a simple Twitter clone API using Finatra, including defining models, controllers, services and tests. Mocking services allows tests to pass without a real backend.

finatratwitterscala
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015

Even for JavaScript software developers well-versed in Agile practices, using test-driven development in the development of Node.js-based webservers can be challenging. In this presentation, I identify solutions to some of the most significant challenges to using TDD to build middleware stacks, with a focus on Express and Koa.

node.jses2015tdd
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing

This presentation deals with a complex approach to application testing in back end and front end parts, tests writing and common mistakes. It also includes a short overview of libraries and frameworks for creation of tests, as well as practical examples of code. Presentation by Pavlo Iuriichuk, Lead Software Engineer, GlobalLogic, Kyiv), delivered at an open techtalk on December 11, 2014. More details - http://globallogic.com.ua/report-web-testing-techtalk-2014

web developmentqaunit testing
No benchmarks
Dockerfile
17
Technical details start here...
18
Shrimp's internals in a few words
●
●
●
19
A picture is worth a thousand words
20

Recommended for you

服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript

Thrift and PasteScript are frameworks for building distributed applications and services. Thrift allows defining data types and interfaces using a simple definition language that can generate code in multiple languages. It uses a compact binary protocol for efficient RPC-style communication between clients and servers. PasteScript builds on WSGI and provides tools like paster for deploying and managing Python web applications, along with reloading and logging capabilities. It integrates with Thrift via server runners and application factories.

Client server part 12
Client server part 12Client server part 12
Client server part 12

This document discusses client-server connections for a library application. It provides code for a CustomHttpClient class that defines methods for performing HTTP GET and POST requests. This includes setting connection timeout parameters. It also provides code for connecting to a MySQL database and inserting login credentials and book borrowing history. The code samples show how to connect between the client and server and interface with the backend database.

Fidl analysis
Fidl analysisFidl analysis
Fidl analysis

The document discusses Fuchsia Inter-process Communication (IPC) using FIDL. It provides an overview of FIDL and describes how a client connects to a server, makes asynchronous and synchronous calls. The client initializes an event loop to wait for responses from the server. The server implements the FIDL protocol and creates bindings to handle client requests and send responses.

What is used inside Shrimp?
21
Let's speak about
22
RESTinio in Shrimp
●
●
●
●
23
External Asio context
●
●
24

Recommended for you

Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js

This document discusses asynchronous programming and avoiding race conditions. It covers how asynchronous actions allow the main program flow to continue processing without blocking on I/O. It also discusses how asynchronous programming works with callbacks and promises rather than sequential execution. It provides examples of using libraries like Async to control asynchronous flows and common pitfalls to avoid like double callbacks and unexpected asynchronous behavior.

node.jsasyncprogramming
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?

HotSpot promises to do the "right" thing for us by identifying our hot code and compiling "just-in-time", but how does HotSpot make those decisions? This presentation aims to detail how HotSpot makes those decisions and how it corrects its mistakes through a series of demos that you run yourself.

java virtual machinejavaazul
marko_go_in_badoo
marko_go_in_badoomarko_go_in_badoo
marko_go_in_badoo

This document discusses the use of Go at Badoo for backend services. It begins by describing Badoo's backend technologies in 2013 and 2014, which included PHP, C/C++, Python, and the introduction of Go in 2014. It then covers Badoo's infrastructure and practices for Go projects, such as logging, testing, and dependencies. Specific Go services developed at Badoo are then summarized, including "Bumped" which was completed in a week by three people. Metrics are provided showing initial performance of ~2800 requests/second but with long GC pauses. The document concludes with tips and examples for profiling and optimizing memory usage in Go.

External Asio context
io_context
io_context
run()
25
External Asio context
// ASIO io_context must outlive sobjectizer.
asio::io_context asio_io_ctx;
// Launch SObjectizer and wait while balancer will be started.
...
so_5::wrapped_env_t sobj{
[&]( so_5::environment_t & env ) {...},
[&]( so_5::environment_params_t & params ) {...} };
// Now we can launch HTTP-server.
restinio::run(
asio_io_ctx,
shrimp::make_http_server_settings(...) );
26
External Asio context
// ASIO io_context must outlive sobjectizer.
asio::io_context asio_io_ctx;
// Launch SObjectizer and wait while balancer will be started.
...
so_5::wrapped_env_t sobj{
[&]( so_5::environment_t & env ) {...},
[&]( so_5::environment_params_t & params ) {...} };
// Now we can launch HTTP-server.
restinio::run(
asio_io_ctx,
shrimp::make_http_server_settings(...) );
27
Asio's io_context object is created.
External Asio context
// ASIO io_context must outlive sobjectizer.
asio::io_context asio_io_ctx;
// Launch SObjectizer and wait while balancer will be started.
...
so_5::wrapped_env_t sobj{
[&]( so_5::environment_t & env ) {...},
[&]( so_5::environment_params_t & params ) {...} };
// Now we can launch HTTP-server.
restinio::run(
asio_io_ctx,
shrimp::make_http_server_settings(...) );
28
SObjectizer is started here.
SObjectizer will be stopped and destroyed before
destruction of io_context.

Recommended for you

CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak

This document summarizes a presentation about using DTrace on OS X. It introduces DTrace as a dynamic tracing tool for user and kernel space. It discusses the D programming language used for writing DTrace scripts, including data types, variables, operators, and actions. Example one-liners and scripts are provided to demonstrate syscall tracking, memory allocation snooping, and hit tracing. The presentation outlines some past security work using DTrace and similar dynamic tracing tools. It concludes with proposing future work like more kernel and USDT tracing as well as Python bindings for DTrace.

confidencedtraceosx
Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby Systems

Aman Gupta's presentation about debugging ruby systems. To view the full recording of his talk, visit: http://www.engineyard.com/video/16710570

Using Libtracecmd to Analyze Your Latency and Performance Troubles
Using Libtracecmd to Analyze Your Latency and Performance TroublesUsing Libtracecmd to Analyze Your Latency and Performance Troubles
Using Libtracecmd to Analyze Your Latency and Performance Troubles

Trying to figure out why your application is responding late can be difficult, especially if it is because of interference from the operating system. This talk will briefly go over how to write a C program that can analyze what in the Linux system is interfering with your application. It will use trace-cmd to enable kernel trace events as well as tracing lock functions, and it will then go over a quick tutorial on how to use libtracecmd to read the created trace.dat file to uncover what is the cause of interference to you application.

External Asio context
// ASIO io_context must outlive sobjectizer.
asio::io_context asio_io_ctx;
// Launch SObjectizer and wait while balancer will be started.
...
so_5::wrapped_env_t sobj{
[&]( so_5::environment_t & env ) {...},
[&]( so_5::environment_params_t & params ) {...} };
// Now we can launch HTTP-server.
restinio::run(
asio_io_ctx,
shrimp::make_http_server_settings(...) );
29
RESTinio is started here.
restinio::run() returns only after
shutdown of HTTP-server.
Logging via spdlog
30
Wrapper around spdlog's logger
class http_server_logger_t
{
public:
http_server_logger_t( std::shared_ptr<spdlog::logger> logger ) : m_logger{std::move(logger)} {}
template<typename Builder> void trace( Builder && msg_builder ) {
log_if_enabled( spdlog::level::trace, std::forward<Builder>(msg_builder) );
}
template<typename Builder> void info( Builder && msg_builder ) {
log_if_enabled( spdlog::level::info, std::forward<Builder>(msg_builder) );
}
...
private:
template<typename Builder> void log_if_enabled(
spdlog::level::level_enum lv, Builder && msg_builder ) {
if( m_logger->should_log(lv) ) { m_logger->log( lv, msg_builder() ); }
}
std::shared_ptr<spdlog::logger> m_logger;
};
31
Tie our wrapper type with RESTinio's traits
struct http_server_traits_t
: public restinio::default_traits_t
{
using logger_t = http_server_logger_t;
using request_handler_t = http_req_router_t;
};
32

Recommended for you

Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon

Solr provides concise summaries of key points from the document: 1. Solr discusses its search architecture including the use of Thrift for service encapsulation and reduced network traffic. Only IDs are returned from searches to reduce index size and enable easy scaling of primary key lookups. 2. Load balancing is discussed, including an algorithm that hashes the query and number of servers to provide server affinity while distributing load evenly. 3. Replication of the index is covered, including challenges with multicast and an implementation using BitTorrent to efficiently replicate files.

solr etsy lucene eurocon thrift bittorrent
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql

This document discusses PostgreSQL and Solaris as a low-cost platform for medium to large scale critical scenarios. It provides an overview of PostgreSQL, highlighting features like MVCC, PITR, and ACID compliance. It describes how Solaris and PostgreSQL integrate well, with benefits like DTrace support, scalability on multicore/multiprocessor systems, and Solaris Cluster support. Examples are given for installing PostgreSQL on Solaris using different methods, configuring zones for isolation, using ZFS for storage, and monitoring performance with DTrace scripts.

Доклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang MeetupДоклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang Meetup

This document summarizes notes from a Go meetup at Badoo in April 2015. It discusses Badoo's use of Go in their backend systems, including replacing 25 C/C++ daemons with Go services. It provides examples of memory profiling Go code to reduce garbage collection pauses. It also discusses using protocol buffers with Go and strategies for reducing allocations when marshaling data.

golangbadoogo
Tie our wrapper type with RESTinio's traits
struct http_server_traits_t
: public restinio::default_traits_t
{
using logger_t = http_server_logger_t;
using request_handler_t = http_req_router_t;
};
33
Now RESTinio server with this traits will use
instance of http_server_logger_t for logging.
Instantiation of our wrapper
[[nodiscard]] inline auto
make_http_server_settings(
unsigned int thread_pool_size,
const app_params_t & params,
std::shared_ptr<spdlog::logger> logger,
so_5::mbox_t req_handler_mbox )
{
...
return restinio::on_thread_pool< http_server_traits_t >( thread_pool_size )
.port( http_srv_params.m_port )
.protocol( ip_protocol(http_srv_params.m_ip_version) )
.address( http_srv_params.m_address )
.handle_request_timeout( std::chrono::seconds(60) )
.write_http_response_timelimit( std::chrono::seconds(60) )
.logger( std::move(logger) )
.request_handler( make_router( params, req_handler_mbox ) );
}
34
Instantiation of our wrapper
[[nodiscard]] inline auto
make_http_server_settings(
unsigned int thread_pool_size,
const app_params_t & params,
std::shared_ptr<spdlog::logger> logger,
so_5::mbox_t req_handler_mbox )
{
...
return restinio::on_thread_pool< http_server_traits_t >( thread_pool_size )
.port( http_srv_params.m_port )
.protocol( ip_protocol(http_srv_params.m_ip_version) )
.address( http_srv_params.m_address )
.handle_request_timeout( std::chrono::seconds(60) )
.write_http_response_timelimit( std::chrono::seconds(60) )
.logger( std::move(logger) )
.request_handler( make_router( params, req_handler_mbox ) );
}
35
Instantiation of our wrapper
[[nodiscard]] inline auto
make_http_server_settings(
unsigned int thread_pool_size,
const app_params_t & params,
std::shared_ptr<spdlog::logger> logger,
so_5::mbox_t req_handler_mbox )
{
...
return restinio::on_thread_pool< http_server_traits_t >( thread_pool_size )
.port( http_srv_params.m_port )
.protocol( ip_protocol(http_srv_params.m_ip_version) )
.address( http_srv_params.m_address )
.handle_request_timeout( std::chrono::seconds(60) )
.write_http_response_timelimit( std::chrono::seconds(60) )
.logger( std::move(logger) )
.request_handler( make_router( params, req_handler_mbox ) );
}
36
Object of type http_server_traits_t::logger_t
(aka http_server_logger_t) will be created here.
Spdlog's logger will be passed to the
constructor of that object.

Recommended for you

Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)

The document discusses various Linux performance analysis tools including lsof to list open files, strace to trace system calls, tcpdump to dump network traffic, perftools from Google for profiling CPU usage, and a Ruby library called perftools.rb for profiling Ruby code. Examples are provided for using these tools to analyze memory usage, slow queries, Ruby interpreter signals, thread scheduling overhead, and identifying hot spots in Ruby web applications.

highload 2011
Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨

This document provides an overview of Node.js application performance analysis and optimization as well as distributed system design. It discusses analyzing and optimizing CPU, memory, file I/O and network I/O usage. It also covers profiling Node.js applications using tools like Linux profiling tools, Node.js libraries, and V8 profiling tools. Lastly it discusses designing distributed systems using single machine and cluster approaches.

node.js;performance tune;distributed;
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy

Presto is an open source distributed SQL query engine for running interactive analytic queries against data sources of all sizes ranging from gigabytes to petabytes. It is written in Java and uses a pluggable backend. Presto is fast due to code generation and runtime compilation techniques. It provides a library and framework for building distributed services and fast Java collections. Plugins allow Presto to connect to different data sources like Hive, Cassandra, MongoDB and more.

presto
Log example (with --restinio-tracing -l trace)
37
ExpressJS-like routing
38
ExpressJS-like routing
using http_req_router_t =
restinio::router::express_router_t<
restinio::router::pcre_regex_engine_t<
restinio::router::pcre_traits_t<
// Max capture groups for regex.
5 > > >;
39
ExpressJS-like routing
using http_req_router_t =
restinio::router::express_router_t<
restinio::router::pcre_regex_engine_t<
restinio::router::pcre_traits_t<
// Max capture groups for regex.
5 > > >;
40
Express router can use different engines.
There are engines based on std::regex, Boost.Regex
and PCRE/PCRE2.
A PCRE-based engine is used here.

Recommended for you

Debugging Ruby
Debugging RubyDebugging Ruby
Debugging Ruby

This document provides information on various debugging and profiling tools that can be used for Ruby including: - lsof to list open files for a process - strace to trace system calls and signals - tcpdump to dump network traffic - google perftools profiler for CPU profiling - pprof to analyze profiling data It also discusses how some of these tools have helped identify specific performance issues with Ruby like excessive calls to sigprocmask and memcpy calls slowing down EventMachine with threads.

debugginggdbperftools
Reverse engineering Swisscom's Centro Grande Modem
Reverse engineering Swisscom's Centro Grande ModemReverse engineering Swisscom's Centro Grande Modem
Reverse engineering Swisscom's Centro Grande Modem

The document discusses reverse engineering the firmware of Swisscom's Centro Grande modems. It identifies several vulnerabilities found, including a command overflow issue that allows complete control of the device by exceeding the input buffer, and multiple buffer overflow issues that can be exploited to execute code remotely by crafting specially formatted XML files. Details are provided on the exploitation techniques and timeline of coordination with Swisscom to address the vulnerabilities.

infosecsecuritycybsec16
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS

This document summarizes a talk given at ApacheCon 2015 about replacing Squid with ATS (Apache Traffic Server) as the proxy server at Yahoo. It discusses the history of using Squid at Yahoo, limitations with Squid that prompted the switch to ATS, key differences in configuration between the two systems, examples of forwarding and reverse proxy use cases, and learnings around managing open source projects and migration testing.

atssquid
ExpressJS-like routing
struct http_server_traits_t
: public restinio::default_traits_t
{
using logger_t = http_server_logger_t;
using request_handler_t = http_req_router_t;
};
41
ExpressJS-like routing
void add_transform_op_handler(
const app_params_t & app_params,
http_req_router_t & router,
so_5::mbox_t req_handler_mbox )
{
router.http_get(
R"(/:path(.*).:ext(.{3,4}))",
restinio::path2regex::options_t{}.strict( true ),
[req_handler_mbox, &app_params]( auto req, auto params ) {...} );
}
42
ExpressJS-like routing
void add_transform_op_handler(
const app_params_t & app_params,
http_req_router_t & router,
so_5::mbox_t req_handler_mbox )
{
router.http_get(
R"(/:path(.*).:ext(.{3,4}))",
restinio::path2regex::options_t{}.strict( true ),
[req_handler_mbox, &app_params]( auto req, auto params ) {...} );
}
43
A route with two arguments ('path' and 'ext') is defined here.
sendfile for serving original files
sendfile() TransmitFile()
44

Recommended for you

ReplacingSquidWithATS
ReplacingSquidWithATSReplacingSquidWithATS
ReplacingSquidWithATS

This document summarizes a talk given at ApacheCon 2015 about replacing Squid with Apache Traffic Server (ATS) as the proxy server at Yahoo. It discusses the history of using Squid at Yahoo, limitations with Squid that led to considering ATS, key differences in configuration between the two, how features like caching, logging, and peering are implemented in each, and lessons learned from the migration process.

Why you should be using structured logs
Why you should be using structured logsWhy you should be using structured logs
Why you should be using structured logs

Structured logs provide more context and are easier to analyze than traditional logs. This document discusses why one should use structured logs and how to implement structured logging in Python. Key points include: - Structured logs add context like metadata, payloads and stack traces to log messages. This makes logs more searchable, reusable and easier to debug. - Benefits of structured logs include easier developer onboarding, improved debugging and monitoring, and the ability to join logs from different systems. - Python's logging module can be used to implement structured logging. This involves customizing the LogRecord and Formatter classes to output log messages as JSON strings. - Considerations for structured logs include potential performance impacts from serialization

structured logsloggingjson
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"

Десь рік тому ми почали працювати над новою версією наших продуктів. Саме тоді ми почали випробовувати різні технології, архітектури, підходи, а головне це — міряти performance, бо без цього в highload проектах взагалі не вижити. При проектуванні “любої” системи нам потрібно знати її ліміти: скільки паралельних запитів може обробити мікросервіс за допустиму latency? як багато запитів може витримати база даних, яку ми використовуємо? як довго потрібно чекати на Push повідомлення? як довго триває розподілена транзакція та між якими сервісами відбувається найбільша затримка? І таких питань у нас було безліч. В процесі тестування ми використовували різний tooling: JMeter, ab, Gatling, але всі вони надавали дуже лімітовані можливості. Нам не вдавалося нормально покрити push flow (WebSockets/SSE), різні бази даних, було складно імітувати різний workloads (update/read). На цій зустрічі я розповім про наш досвід застосування load testing: що використовуємо для тестування баз даних, мікросервісів; як готуємо Pull/Push тести та як адаптуємо тести під різні протоколи (HTTP/WebSockets/SSE); які виникають проблеми з замірами latency. Моя доповідь дуже практична, тому після неї ви зможете з легкістю почати застосовувати load testing у себе на проекті.

load testingfwdaysdotnet
sendfile for serving original files
[[nodiscard]] restinio::request_handling_status_t
serve_as_regular_file(const std::string & root_dir, restinio::request_handle_t req, image_format_t image_format)
{
const auto full_path = make_full_path( root_dir, req->header().path() );
try {
auto sf = restinio::sendfile( full_path );
const auto last_modified = sf.meta().last_modified_at();
auto resp = req->create_response();
return set_common_header_fields_for_image_resp( last_modified, resp )
.append_header( restinio::http_field::content_type, image_content_type_from_img_format(image_format) )
.append_header( restinio::http_header_field_t{
http_header::shrimp_image_src_hf(),
image_src_to_str( http_header::image_src_t::sendfile ) } )
.set_body( std::move(sf) )
.done();
}
catch(...) { }
return do_404_response( std::move( req ) );
}
45
sendfile for serving original files
[[nodiscard]] restinio::request_handling_status_t
serve_as_regular_file(const std::string & root_dir, restinio::request_handle_t req, image_format_t image_format)
{
const auto full_path = make_full_path( root_dir, req->header().path() );
try {
auto sf = restinio::sendfile( full_path );
const auto last_modified = sf.meta().last_modified_at();
auto resp = req->create_response();
return set_common_header_fields_for_image_resp( last_modified, resp )
.append_header( restinio::http_field::content_type, image_content_type_from_img_format(image_format) )
.append_header( restinio::http_header_field_t{
http_header::shrimp_image_src_hf(),
image_src_to_str( http_header::image_src_t::sendfile ) } )
.set_body( std::move(sf) )
.done();
}
catch(...) { }
return do_404_response( std::move( req ) );
}
46
sendfile operation is defined here.
sendfile for serving original files
[[nodiscard]] restinio::request_handling_status_t
serve_as_regular_file(const std::string & root_dir, restinio::request_handle_t req, image_format_t image_format)
{
const auto full_path = make_full_path( root_dir, req->header().path() );
try {
auto sf = restinio::sendfile( full_path );
const auto last_modified = sf.meta().last_modified_at();
auto resp = req->create_response();
return set_common_header_fields_for_image_resp( last_modified, resp )
.append_header( restinio::http_field::content_type, image_content_type_from_img_format(image_format) )
.append_header( restinio::http_header_field_t{
http_header::shrimp_image_src_hf(),
image_src_to_str( http_header::image_src_t::sendfile ) } )
.set_body( std::move(sf) )
.done();
}
catch(...) { }
return do_404_response( std::move( req ) );
}
47
sendfile operation is used here for sending file's content as
response's body.
The next big topic
48

Recommended for you

Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBox

The document discusses using TorqueBox, a Ruby application server based on JRuby and JBoss AS7, to deploy a Rails application in production. It compares various deployment options from rolling your own infrastructure to using a platform as a service like Heroku. TorqueBox provides a middle ground where it handles services like caching, background jobs, scheduling, and clustering but still allows customization. The document walks through migrating an existing Rails app's Delayed::Job and caching implementations to use TorqueBox equivalents to simplify the deployment.

torqueboxrubynationruby
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015

This document discusses Rhebok, a high performance Rack handler written in Ruby. Rhebok uses a prefork architecture for concurrency and achieves 1.5-2x better performance than Unicorn. It implements efficient network I/O using techniques like IO timeouts, TCP_NODELAY, and writev(). Rhebok also uses the ultra-fast PicoHTTPParser for HTTP request parsing. The document provides an overview of Rhebok, benchmarks showing its performance, and details on its internals and architecture.

Joker 2015 - Валеев Тагир - Что же мы измеряем?
Joker 2015 - Валеев Тагир - Что же мы измеряем?Joker 2015 - Валеев Тагир - Что же мы измеряем?
Joker 2015 - Валеев Тагир - Что же мы измеряем?

The document discusses performance comparisons between simple for loops and Java Stream API operations. Benchmark tests show that streams can be 6-7 times slower for simple operations like summing integers in a range. However, with JIT compilation and optimization over time, the stream performance improves and approaches the performance of simple loops. Factors like JIT compilation, on-stack replacement, and lambda expression overhead contribute to initial stream performance differences.

javaprogramming
Actors in Shrimp
●
●
49
Actors in Shrimp
50
Actors in Shrimp
51
transformer agent
class a_transformer_t final : public so_5::agent_t
{
public:
struct resize_request_t final : public so_5::message_t {...};
a_transformer_t(context_t ctx, std::shared_ptr<spdlog::logger> logger, storage_params_t cfg);
void so_define_agent() override {
so_subscribe_self().event( &a_transformer_t::on_resize_request );
}
private:
...
on_resize_request(mutable_mhood_t<resize_request_t> cmd);
...
};
52

Recommended for you

Docker tips-for-java-developers
Docker tips-for-java-developersDocker tips-for-java-developers
Docker tips-for-java-developers

With the increasing adoption of cloud native technologies and containerization; the gap between Java development and system administration is decreasing. Whether you are using Docker Swarm, Kubernetes or Mesos as a container orchestrator; fundamental challenges for running docker in production are common. In this talk, I would like to share some of the basic linux concepts (like memory management, CPU, IO, sockets, file descriptors, signals, OOM killer) every Java Developer should know to be able to perform effective configuration and troubleshooting for docker containers.

jvmdockercpu
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)

This is an updated version of slides from my talk on the C++ CoreHard Autumn 2016 conference. The Actor Model which is currently trending in software development is a popular design approach when it comes to complex applications. Many systems are written in Erlang (Akka framework) are designed with the Actor Model in their core. But Erlang and Akka are managed environments and safe programming languages. Is it worth using the Actor Model in C++? If yes, where to look and what to use? The talk will cover all these topics.

c++actormodelmessagepassing
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)

SObjectizer is a C++ framework for building robust multithreaded applications based on asynchronous message passing. It uses actor model, publish-subscribe, and communicating sequential processes abstractions. SObjectizer was developed in the 1990s and evolved into SObjectizer-5, which is still maintained today. SObjectizer provides cross-platform support and allows building distributed systems or using message passing on plain threads. It includes features like timers, message boxes, and select() for non-blocking sends and receives. While powerful for concurrency, SObjectizer requires additional libraries for building distributed applications.

sobjectizercplusplusactormodel
transformer agent
class a_transformer_t final : public so_5::agent_t
{
public:
struct resize_request_t final : public so_5::message_t {...};
a_transformer_t(context_t ctx, std::shared_ptr<spdlog::logger> logger, storage_params_t cfg);
void so_define_agent() override {
so_subscribe_self().event( &a_transformer_t::on_resize_request );
}
private:
...
on_resize_request(mutable_mhood_t<resize_request_t> cmd);
...
};
53
Message to be handled.
transformer agent
class a_transformer_t final : public so_5::agent_t
{
public:
struct resize_request_t final : public so_5::message_t {...};
a_transformer_t(context_t ctx, std::shared_ptr<spdlog::logger> logger, storage_params_t cfg);
void so_define_agent() override {
so_subscribe_self().event( &a_transformer_t::on_resize_request );
}
private:
...
on_resize_request(mutable_mhood_t<resize_request_t> cmd);
...
};
54
Subscription to the message.
When message resize_request_t arrives the
on_resize_request() method will be called.
Type of message to be subscribed is deduced from
handler's prototype.
transform_manager agent
55
transform_manager agent (1)
class a_transform_manager_t final : public so_5::agent_t
{
public:
struct resize_request_t final : public so_5::message_t {...};
struct resize_result_t final : public so_5::message_t {...};
struct delete_cache_request_t final : public so_5::message_t {...};
a_transform_manager_t(context_t ctx, std::shared_ptr<spdlog::logger> logger);
void so_define_agent() override;
void so_evt_start() override;
...
56

Recommended for you

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)

SObjectizer is a framework for building robust multithreaded applications based on the actor model. It uses asynchronous message passing and high-level abstractions like actors, publish-subscribe, and communicating sequential processes. SObjectizer has been in development since the 1990s and is mature, stable, cross-platform, easy to use, and free. It provides features like multiple dispatcher types, hierarchical state machines, and message chains. Developers can build entire applications on SObjectizer or integrate it into other applications.

c++c++17actormodel
[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...

Слайды одноименного доклада с конференции C++ CoreHard Autumn 2018 (г.Минск, 2018.11.03). Краткое описание доклада: На предыдущих конференциях C++ CoreHard автор доклада рассказывал про Модель Акторов и опыт ее использования в C++. Но Модель Акторов -- это далеко не единственный способ борьбы со сложностью при работе с многопоточностью. Давайте попробуем поговорить о том, что еще можно применить и как это может выглядеть в C++.

actormodelsobjectizerconcurrency
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...
Акторы в C++: взгляд старого практикующего актородела (St. Petersburg C++ Use...

Автор доклада более 16 лет отвечает за развитие Open-Source фреймворка SObjectizer -- одно��о из немногих живых, эволюционирующих, кросс-платформенных фреймворков для C++, базирующихся на Модели Акторов. При этом SObjectizer никогда не был исследовательским экспериментом и с самого начала использовался в ряде business-critical проектов. За годы разработки и эксплуатации SObjectizer накопился некоторый практический опыт использования акторов в С++, которым докладчик поделится со слушателями. Речь пойдет о том, почему Модель Акторов выглядит привлекательной, где и когда ее выгодно использовать. Какие особенности накладывает именно С++ и разумно ли использовать Модель Акторов в C++? Почему реализации Модели Акторов для C++ настолько разные и почему SObjectizer получился именно таким?

actormodelc++sobjectizer
transform_manager agent (1)
class a_transform_manager_t final : public so_5::agent_t
{
public:
struct resize_request_t final : public so_5::message_t {...};
struct resize_result_t final : public so_5::message_t {...};
struct delete_cache_request_t final : public so_5::message_t {...};
a_transform_manager_t(context_t ctx, std::shared_ptr<spdlog::logger> logger);
void so_define_agent() override;
void so_evt_start() override;
...
57
Those are "public" messages. They are sent to transform_manager by external
entities:
● resize_request_t and delete_cache_request_t are sent by HTTP-server;
● resize_result_t is sent by transformer agent.
transform_manager agent (2)
private :
struct negative_delete_cache_response_t : public so_5::message_t {...};
struct clear_cache_t final : public so_5::signal_t {};
struct check_pending_requests_t final : public so_5::signal_t {};
...
void on_resize_request(mutable_mhood_t<resize_request_t> cmd);
void on_resize_result(mutable_mhood_t<resize_result_t> cmd);
void on_delete_cache_request(mutable_mhood_t<delete_cache_request_t> cmd);
void on_negative_delete_cache_response(
mutable_mhood_t<negative_delete_cache_response_t> cmd);
void on_clear_cache(mhood_t<clear_cache_t>);
void on_check_pending_requests(mhood_t<check_pending_requests_t>);
...
};
58
transform_manager agent (2)
private :
struct negative_delete_cache_response_t : public so_5::message_t {...};
struct clear_cache_t final : public so_5::signal_t {};
struct check_pending_requests_t final : public so_5::signal_t {};
...
void on_resize_request(mutable_mhood_t<resize_request_t> cmd);
void on_resize_result(mutable_mhood_t<resize_result_t> cmd);
void on_delete_cache_request(mutable_mhood_t<delete_cache_request_t> cmd);
void on_negative_delete_cache_response(
mutable_mhood_t<negative_delete_cache_response_t> cmd);
void on_clear_cache(mhood_t<clear_cache_t>);
void on_check_pending_requests(mhood_t<check_pending_requests_t>);
...
};
59
Those are "private" message and signals. transform_manager sends them to itself.
transform_manager agent (3)
void a_transform_manager_t::so_define_agent()
{
so_subscribe_self()
.event( &a_transform_manager_t::on_resize_request )
.event( &a_transform_manager_t::on_resize_result )
.event( &a_transform_manager_t::on_delete_cache_request )
.event( &a_transform_manager_t::on_negative_delete_cache_response )
.event( &a_transform_manager_t::on_clear_cache )
.event( &a_transform_manager_t::on_check_pending_requests );
}
60

Recommended for you

Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?Акторы на C++: стоило ли оно того?
Акторы на C++: стоило ли оно того?

Слайды одноименного доклада с конференции "C++ Russia 2018". В докладе речь идет о том, насколько C++ мешает и насколько C++ помогает в разработке акторного фреймворка для C++.

sobjectizercplusplusactormodel
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

The document discusses the history and evolution of the C++ programming language over approximately 30 years from the 1980s to the present. It describes how C++ gained popularity due to factors like representing an easy upgrade from C, the need for an efficient yet powerful language for developing applications on weaker computers of the time, and the rise of object-oriented programming. Examples are provided of sorting a collection of data structures to demonstrate C++ features from different eras. The talk aims to advocate for C++ and address myths about its usage.

cplusplus
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

Slides from my presentation from GECon-2017 conference: https://events.epam.com/events/gecon-2017 It covers the following topics: A bit of C++ evolution history. Why C++ became popular and why C++ started to lose its popularity. Why C++ is a Monster? If C ++ is a monster, then why does someone need C++? How to use C++ safely and efficiently? Where and when C++ can be used. If it can... Pressure to C++ from competitors. Real and imaginary.

c++
Basic working scheme
a_transform_manager_t::resize_request_t
61
Basic working scheme
a_transform_manager_t::resize_request_t
62
void handle_resize_op_request(
const so_5::mbox_t & req_handler_mbox,
image_format_t image_format,
const restinio::query_string_params_t & qp,
restinio::request_handle_t req )
{
try_to_handle_request( [&]{
auto op_params = transform::resize_params_t::make(
restinio::opt_value< std::uint32_t >( qp, "width" ),
restinio::opt_value< std::uint32_t >( qp, "height" ),
restinio::opt_value< std::uint32_t >( qp, "max" ) );
transform::resize_params_constraints_t{}.check( op_params );
std::string image_path{ req->header().path() };
so_5::send< so_5::mutable_msg<a_transform_manager_t::resize_request_t> >(
req_handler_mbox,
std::move(req), std::move(image_path), image_format, op_params );
},
req );
}
Basic working scheme
a_transformer_t::resize_request_t
63
Basic working scheme
a_transformer_t::resize_request_t
64
void a_transform_manager_t::try_initiate_pending_requests_processing()
{
while( !m_free_workers.empty() && !m_pending_requests.empty() ) {
auto atoken = m_pending_requests.oldest().value();
const auto key = atoken.key();
m_pending_requests.extract_values_for_key( std::move(atoken),
[&]( auto && value ) {
m_inprogress_requests.insert( transform::resize_request_key_t{key}, std::move(value) );
} );
auto worker = std::move(m_free_workers.top());
m_free_workers.pop();
m_logger->trace("initiate processing of a request; request_key={}, worker_mbox={}",
key, worker->id());
so_5::send< so_5::mutable_msg<a_transformer_t::resize_request_t> >(worker, key, so_direct_mbox());
}
}

Recommended for you

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

This part describes a feature which was introduced in v.5.5.19: an ability to send mutable messages with guarantees that it will be delivered to at most one receiver.

messagepassingsobjectizeractormodel
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?

Actor model which is currently trending in software development is a popular design approach when it comes to complex applications. Many systems written in Erlang (Akka framework) are designed with actor model in their core. But Erlang and Akka are managed environments and safe programming languages. Is it worth using actor model in C++? If yes, where to look and what to use? The talk will cover all these topics.

actormodelc++messagepassing
Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++Шишки, набитые за 15 лет использования акторов в C++
Шишки, набитые за 15 лет использования акторов в C++

Слайды доклада на конференции C++ Corehard Winter 2017 (г.Минск). Автор доклада давно и успешно использует Модель Акторов при разработке приложений на C++. В основном это был положительный опыт. Но есть некоторые неочевидные моменты, про которые было бы хорошо узнать заранее. О том, где использование Модели Акторов уместно, а где нет, на какие грабли довелось наступить, какие шишки были набиты, как можно упростить себе жизнь и пойдет речь в докладе.

actormodelsobjectizerconcurrency
Basic working scheme
a_transform_manager_t::resize_result_t
65
Basic working scheme
a_transform_manager_t::resize_result_t
66
void a_transformer_t::on_resize_request(
mutable_mhood_t<resize_request_t> cmd)
{
auto result = handle_resize_request( cmd->m_key );
so_5::send< so_5::mutable_msg<a_transform_manager_t::resize_result_t> >(
cmd->m_reply_to,
so_direct_mbox(),
std::move(cmd->m_key),
std::move(result) );
}
Basic working scheme
67
Basic working scheme
68
void a_transform_manager_t::on_resize_result(
mutable_mhood_t<resize_result_t> cmd )
{
m_logger->trace( "resize_result received; request_key={}, worker_mbox={}",
cmd->m_key,
cmd->m_worker->id() );
m_free_workers.push( std::move(cmd->m_worker) );
try_initiate_pending_requests_processing();
auto key = std::move(cmd->m_key);
auto requests = extract_inprogress_requests(
std::move(m_inprogress_requests.find_first_for_key( key ).value()) );
std::visit( variant_visitor{
[&]( successful_resize_t & result ) {
on_successful_resize( std::move(key), result, std::move(requests) );
},
[&]( failed_resize_t & result ) {
on_failed_resize( std::move(key), result, std::move(requests) );
} },
cmd->m_result );
}

Recommended for you

Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?Для чего мы делали свой акторный фреймворк и что из этого вышло?
Для чего мы делали свой акторный фреймворк и что из этого вышло?

Презентация доклада для конференции C++ Russia 2017.

actormodelmessagepassingmultithreading
Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?Модель акторов и C++ что, зачем и как?
Модель акторов и C++ что, зачем и как?

Презентация доклада на конференции CoreHard C++ Autumn 2016 (Минск, 2016.10.22)

c++multithreadingmessagepassing
Dive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message ChainsDive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message Chains

The next part of "Dive into SObjectizer-5.5" serie. This part introduces message chains. Message chains allows to use CSP-like concurrency in C++.

cplusplussobjectizermultithreading
Basic working scheme
69
void a_transform_manager_t::on_resize_result(
mutable_mhood_t<resize_result_t> cmd )
{
m_logger->trace( "resize_result received; request_key={}, worker_mbox={}",
cmd->m_key,
cmd->m_worker->id() );
m_free_workers.push( std::move(cmd->m_worker) );
try_initiate_pending_requests_processing();
auto key = std::move(cmd->m_key);
auto requests = extract_inprogress_requests(
std::move(m_inprogress_requests.find_first_for_key( key ).value()) );
std::visit( variant_visitor{
[&]( successful_resize_t & result ) {
on_successful_resize( std::move(key), result, std::move(requests) );
},
[&]( failed_resize_t & result ) {
on_failed_resize( std::move(key), result, std::move(requests) );
} },
cmd->m_result );
}
void a_transform_manager_t::on_failed_resize(
transform::resize_request_key_t key,
failed_resize_t & result,
original_request_container_t requests )
{
m_logger->warn( "failed resize; request_key={}, reason={}", key, result.m_reason );
for( auto & rq : requests )
{
m_logger->trace( "sending negative response back; request_key={}, connection_id={}",
key, rq->m_http_req->connection_id() );
do_404_response( std::move(rq->m_http_req) );
}
}
Providing work threads to agents
70
Providing work threads to agents (1)
[[nodiscard]] so_5::mbox_t
create_agents(
spdlog::sink_ptr logger_sink,
const shrimp::app_params_t & app_params,
so_5::environment_t & env,
unsigned int worker_threads_count )
{
using namespace shrimp;
using namespace so_5::disp::one_thread; // For create_private_disp.
so_5::mbox_t manager_mbox;
env.introduce_coop([&]( so_5::coop_t & coop ) {
auto manager = coop.make_agent_with_binder< a_transform_manager_t >(
create_private_disp( env, "manager" )->binder(),
make_logger( "manager", logger_sink ) );
manager_mbox = manager->so_direct_mbox();
71
Providing work threads to agents (1)
[[nodiscard]] so_5::mbox_t
create_agents(
spdlog::sink_ptr logger_sink,
const shrimp::app_params_t & app_params,
so_5::environment_t & env,
unsigned int worker_threads_count )
{
using namespace shrimp;
using namespace so_5::disp::one_thread; // For create_private_disp.
so_5::mbox_t manager_mbox;
env.introduce_coop([&]( so_5::coop_t & coop ) {
auto manager = coop.make_agent_with_binder< a_transform_manager_t >(
create_private_disp( env, "manager" )->binder(),
make_logger( "manager", logger_sink ) );
manager_mbox = manager->so_direct_mbox();
72
transform_manager agent is created and is bound to separate
one_thread dispatcher. It means that transform_manager will
have its own work thread.

Recommended for you

Dive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: DispatchersDive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: Dispatchers

This document provides an overview of dispatchers in SObjectizer-5.5. It explains that dispatchers manage event queues and worker threads to handle agents' events. Different types of dispatchers exist, including one_thread, active_obj, thread_pool, and priority-based dispatchers. Public dispatchers are accessible by name, while private dispatchers are created and handled directly. The document discusses how dispatchers are used to simplify multithreading development in SObjectizer.

sobjectizerconcurrencymessagepassing
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

The document summarizes new features in SObjectizer version 5.5.9, including the ability to use arbitrary user types as message types, a new wrapped_env_t class to simplify usage of SObjectizer with other frameworks, and a new message delivery tracing mechanism to simplify debugging applications.

messagepassingactormodelconcurrency
Dive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message LimitsDive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message Limits

Next part of serie with deep dive into SObjectizer-5.5. A brief explanation of message limits feature. This feature allows to protect agents from overloading in simple situations and can be used as building blocks for more complex and domain-specific overload control schemes.

multithreadingconcurrencysobjectizer
Providing work threads to agents (2)
// Every worker will work on its own private dispatcher.
for( unsigned int worker{}; worker < worker_threads_count; ++worker )
{
const auto worker_name = fmt::format( "worker_{}", worker );
auto transformer = coop.make_agent_with_binder< a_transformer_t >(
create_private_disp( env, worker_name )->binder(),
make_logger( worker_name, logger_sink ),
app_params.m_storage );
manager->add_worker( transformer->so_direct_mbox() );
}
} );
return manager_mbox;
}
73
Providing work threads to agents (2)
// Every worker will work on its own private dispatcher.
for( unsigned int worker{}; worker < worker_threads_count; ++worker )
{
const auto worker_name = fmt::format( "worker_{}", worker );
auto transformer = coop.make_agent_with_binder< a_transformer_t >(
create_private_disp( env, worker_name )->binder(),
make_logger( worker_name, logger_sink ),
app_params.m_storage );
manager->add_worker( transformer->so_direct_mbox() );
}
} );
return manager_mbox;
}
74
The same is for every transformer agent.
And now the end is near...
75
The results of the experiment
76

Recommended for you

Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous InteractionDive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction

Next part of serie with deep dive into features of SObjectizer-5.5. A brief explanation of synchronous interaction between agents.

messagepassingsobjectizeractormodel
Dive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: TimersDive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: Timers

This document discusses timers in SObjectizer-5.5, including delayed messages which are delivered after a specified delay, periodic messages which are delivered repeatedly with a specified period, and cancellation of timers. It provides examples of how to send delayed and periodic messages using send_delayed(), send_periodic(), and schedule_timer(), and how timers can be cancelled by calling release() on the timer ID or letting the last timer ID go out of scope.

multithreadingberkeley software distributionactormodel
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

The document summarizes the new features in SObjectizer version 5.5.8, including the introduction of agent priorities, three new dispatchers that support priorities, and simplifications for working with ad-hoc agents. Agent priorities can be set during construction and are used by some new dispatchers to prioritize event handling. The new dispatchers include two that handle all priorities on one thread and one that uses a dedicated thread per priority. Updates also simplify usage of ad-hoc agents by allowing agent contexts and proxies instead of direct mailboxes.

berkeley software distributionactormodelmultithreading
It's not a 10-lines HelloWorld
77
It's not a 10-lines HelloWorld
#include <restinio/all.hpp>
int main()
{
restinio::run(
restinio::on_this_thread<>()
.port(8080)
.address("localhost")
.request_handler([](auto req) {
return req->create_response().set_body("Hello, World!").done();
}));
return 0;
}
78
It's not a 10-lines HelloWorld
#include <restinio/all.hpp>
int main()
{
restinio::run(
restinio::on_this_thread<>()
.port(8080)
.address("localhost")
.request_handler([](auto req) {
return req->create_response().set_body("Hello, World!").done();
}));
return 0;
}
79
It's not a 10-lines HelloWorld
#include <restinio/all.hpp>
int main()
{
restinio::run(
restinio::on_this_thread<>()
.port(8080)
.address("localhost")
.request_handler([](auto req) {
return req->create_response().set_body("Hello, World!").done();
}));
return 0;
}
80

Recommended for you

Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...
Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...
Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...

IN Dubai [WHATSAPP:Only (+971588192166**)] Abortion Pills For Sale In Dubai** UAE** Mifepristone and Misoprostol Tablets Available In Dubai** UAE CONTACT DR. SINDY Whatsapp +971588192166* We Have Abortion Pills / Cytotec Tablets /Mifegest Kit Available in Dubai** Sharjah** Abudhabi** Ajman** Alain** Fujairah** Ras Al Khaimah** Umm Al Quwain** UAE** Buy cytotec in Dubai +971588192166* '''Abortion Pills near me DUBAI | ABU DHABI|UAE. Price of Misoprostol** Cytotec” +971588192166* ' Dr.SINDY ''BUY ABORTION PILLS MIFEGEST KIT** MISOPROSTOL** CYTOTEC PILLS IN DUBAI** ABU DHABI**UAE'' Contact me now via What's App… abortion pills in dubai Mtp-Kit Prices abortion pills available in dubai/abortion pills for sale in dubai/abortion pills in uae/cytotec dubai/abortion pills in abu dhabi/abortion pills available in abu dhabi/abortion tablets in uae … abortion Pills Cytotec also available Oman Qatar Doha Saudi Arabia Bahrain Above all** Cytotec Abortion Pills are Available In Dubai / UAE** you will be very happy to do abortion in Dubai we are providing cytotec 200mg abortion pills in Dubai** UAE. Medication abortion offers an alternative to Surgical Abortion for women in the early weeks of pregnancy. We only offer abortion pills from 1 week-6 Months. We then advise you to use surgery if it's beyond 6 months. Our Abu Dhabi** Ajman** Al Ain** Dubai** Fujairah** Ras Al Khaimah (RAK)** Sharjah** Umm Al Quwain (UAQ) United Arab Emirates Abortion Clinic provides the safest and most advanced techniques for providing non-surgical** medical and surgical abortion methods for early through late second trimester** including the Abortion By Pill Procedure (RU 486** Mifeprex** Mifepristone** early options French Abortion Pill)** Tamoxifen** Methotrexate and Cytotec (Misoprostol). The Abu Dhabi** United Arab Emirates Abortion Clinic performs Same Day Abortion Procedure using medications that are taken on the first day of the office visit and will cause the abortion to occur generally within 4 to 6 hours (as early as 30 minutes) for patients who are 3 to 12 weeks pregnant. When Mifepristone and Misoprostol are used** 50% of patients complete in 4 to 6 hours; 75% to 80% in 12 hours; and 90% in 24 hours. We use a regimen that allows for completion without the need for surgery 99% of the time. All advanced second trimester and late term pregnancies at our Tampa clinic (17 to 24 weeks or greater) can be completed within 24 hours or less 99% of the time without the need for surgery. The procedure is completed with minimal to no complications. Our Women's Health Center located in Abu Dhabi** United Arab Emirates** uses the latest medications for medical abortions (RU-486** Mifeprex** Mifegyne** Mifepristone** early options French abortion pill)** Methotrexate and Cytotec (Misoprostol). The safety standards of our Abu Dhabi** United Arab Emirates Abortion Doctors remain unparalleled. They consistently maintain the lowest complication rates throughout the nation. Our

Cultural Shifts: Embracing DevOps for Organizational Transformation
Cultural Shifts: Embracing DevOps for Organizational TransformationCultural Shifts: Embracing DevOps for Organizational Transformation
Cultural Shifts: Embracing DevOps for Organizational Transformation

Mindfire Solutions specializes in DevOps services, facilitating digital transformation through streamlined software development and operational efficiency. Their expertise enhances collaboration, accelerates delivery cycles, and ensures scalability using cloud-native technologies. Mindfire Solutions empowers businesses to innovate rapidly and maintain competitive advantage in dynamic market landscapes.

devops servicesdevops consulting servicesexpertise devops
dachnug51 - HCL Sametime 12 as a Software Appliance.pdf
dachnug51 - HCL Sametime 12 as a Software Appliance.pdfdachnug51 - HCL Sametime 12 as a Software Appliance.pdf
dachnug51 - HCL Sametime 12 as a Software Appliance.pdf

dachnug51 | HCL Sametime 12 as a Software Appliance | Erik Schwalb

dnugdachnugdachnug51
New ideas for implementation
81
We are open for new ideas...
82
References at one place
83
That's all
84

Recommended for you

Overview of ERP - Mechlin Technologies.pptx
Overview of ERP - Mechlin Technologies.pptxOverview of ERP - Mechlin Technologies.pptx
Overview of ERP - Mechlin Technologies.pptx

This PowerPoint presentation provides a comprehensive overview of Enterprise Resource Planning (ERP) systems. It covers the fundamental concepts, benefits, and key functionalities of ERP software, illustrating how it integrates various business processes into a unified system. From finance and HR to supply chain and customer relationship management, ERP facilitates efficient data management and decision-making across organizations. Whether you're new to ERP or looking to deepen your understanding, this presentation offers valuable insights into leveraging ERP for business success.

erp development serviceserp software developmenterp software services
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...

AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introduction.pdf

awscloudpractitioner
Leading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptxLeading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptx

Taskroup is the leading project management tool designed to streamline your workflow and boost productivity. Try it now! https://taskroup.com/about/

leading project management

More Related Content

What's hot

Serverless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopServerless, The Middy Way - Workshop
Serverless, The Middy Way - Workshop
Luciano Mammino
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
knight1128
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
David Gómez García
 
Forgive me for i have allocated
Forgive me for i have allocatedForgive me for i have allocated
Forgive me for i have allocated
Tomasz Kowalczewski
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
cacois
 
Behind modern concurrency primitives
Behind modern concurrency primitivesBehind modern concurrency primitives
Behind modern concurrency primitives
Bartosz Sypytkowski
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams
Bartosz Sypytkowski
 
Callbacks and control flow in Node js
Callbacks and control flow in Node jsCallbacks and control flow in Node js
Callbacks and control flow in Node js
Thomas Roch
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
Beyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js TransactionsBeyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js Transactions
Terral R Jordan
 
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
Micha Kops
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
Dhaval Dalal
 
Finatra v2
Finatra v2Finatra v2
Finatra v2
Steve Cosenza
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015
Morris Singer
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
GlobalLogic Ukraine
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
Qiangning Hong
 
Client server part 12
Client server part 12Client server part 12
Client server part 12
fadlihulopi
 
Fidl analysis
Fidl analysisFidl analysis
Fidl analysis
TekObserver
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
Piotr Pelczar
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
Doug Hawkins
 

What's hot (20)

Serverless, The Middy Way - Workshop
Serverless, The Middy Way - WorkshopServerless, The Middy Way - Workshop
Serverless, The Middy Way - Workshop
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 
Java9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidadJava9 Beyond Modularity - Java 9 más allá de la modularidad
Java9 Beyond Modularity - Java 9 más allá de la modularidad
 
Forgive me for i have allocated
Forgive me for i have allocatedForgive me for i have allocated
Forgive me for i have allocated
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Behind modern concurrency primitives
Behind modern concurrency primitivesBehind modern concurrency primitives
Behind modern concurrency primitives
 
Akka.NET streams and reactive streams
Akka.NET streams and reactive streamsAkka.NET streams and reactive streams
Akka.NET streams and reactive streams
 
Callbacks and control flow in Node js
Callbacks and control flow in Node jsCallbacks and control flow in Node js
Callbacks and control flow in Node js
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
Beyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js TransactionsBeyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js Transactions
 
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
 
DRYing to Monad in Java8
DRYing to Monad in Java8DRYing to Monad in Java8
DRYing to Monad in Java8
 
Finatra v2
Finatra v2Finatra v2
Finatra v2
 
Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015Unit Testing Express and Koa Middleware in ES2015
Unit Testing Express and Koa Middleware in ES2015
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
Client server part 12
Client server part 12Client server part 12
Client server part 12
 
Fidl analysis
Fidl analysisFidl analysis
Fidl analysis
 
Asynchronous programming done right - Node.js
Asynchronous programming done right - Node.jsAsynchronous programming done right - Node.js
Asynchronous programming done right - Node.js
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 

Similar to Shrimp: A Rather Practical Example Of Application Development With RESTinio and SObjectizer

marko_go_in_badoo
marko_go_in_badoomarko_go_in_badoo
marko_go_in_badoo
Marko Kevac
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
PROIDEA
 
Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby Systems
Engine Yard
 
Using Libtracecmd to Analyze Your Latency and Performance Troubles
Using Libtracecmd to Analyze Your Latency and Performance TroublesUsing Libtracecmd to Analyze Your Latency and Performance Troubles
Using Libtracecmd to Analyze Your Latency and Performance Troubles
ScyllaDB
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
Giovanni Fernandez-Kincade
 
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql
Emanuel Calvo
 
Доклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang MeetupДоклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang Meetup
Badoo Development
 
Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)
Ontico
 
Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨
flyinweb
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
Dongmin Yu
 
Debugging Ruby
Debugging RubyDebugging Ruby
Debugging Ruby
Aman Gupta
 
Reverse engineering Swisscom's Centro Grande Modem
Reverse engineering Swisscom's Centro Grande ModemReverse engineering Swisscom's Centro Grande Modem
Reverse engineering Swisscom's Centro Grande Modem
Cyber Security Alliance
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
Kit Chan
 
ReplacingSquidWithATS
ReplacingSquidWithATSReplacingSquidWithATS
ReplacingSquidWithATS
Chiranjeevi Jaladi
 
Why you should be using structured logs
Why you should be using structured logsWhy you should be using structured logs
Why you should be using structured logs
Stefan Krawczyk
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
Fwdays
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBox
bobmcwhirter
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Masahiro Nagano
 
Joker 2015 - Валеев Тагир - Что же мы измеряем?
Joker 2015 - Валеев Тагир - Что же мы измеряем?Joker 2015 - Валеев Тагир - Что же мы измеряем?
Joker 2015 - Валеев Тагир - Что же мы измеряем?
tvaleev
 
Docker tips-for-java-developers
Docker tips-for-java-developersDocker tips-for-java-developers
Docker tips-for-java-developers
Aparna Chaudhary
 

Similar to Shrimp: A Rather Practical Example Of Application Development With RESTinio and SObjectizer (20)

marko_go_in_badoo
marko_go_in_badoomarko_go_in_badoo
marko_go_in_badoo
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
 
Debugging Ruby Systems
Debugging Ruby SystemsDebugging Ruby Systems
Debugging Ruby Systems
 
Using Libtracecmd to Analyze Your Latency and Performance Troubles
Using Libtracecmd to Analyze Your Latency and Performance TroublesUsing Libtracecmd to Analyze Your Latency and Performance Troubles
Using Libtracecmd to Analyze Your Latency and Performance Troubles
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
Osol Pgsql
Osol PgsqlOsol Pgsql
Osol Pgsql
 
Доклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang MeetupДоклад Антона Поварова "Go in Badoo" с Golang Meetup
Доклад Антона Поварова "Go in Badoo" с Golang Meetup
 
Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)
 
Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨Nodejs性能分析优化和分布式设计探讨
Nodejs性能分析优化和分布式设计探讨
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
Debugging Ruby
Debugging RubyDebugging Ruby
Debugging Ruby
 
Reverse engineering Swisscom's Centro Grande Modem
Reverse engineering Swisscom's Centro Grande ModemReverse engineering Swisscom's Centro Grande Modem
Reverse engineering Swisscom's Centro Grande Modem
 
Replacing Squid with ATS
Replacing Squid with ATSReplacing Squid with ATS
Replacing Squid with ATS
 
ReplacingSquidWithATS
ReplacingSquidWithATSReplacingSquidWithATS
ReplacingSquidWithATS
 
Why you should be using structured logs
Why you should be using structured logsWhy you should be using structured logs
Why you should be using structured logs
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
 
Complex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBoxComplex Made Simple: Sleep Better with TorqueBox
Complex Made Simple: Sleep Better with TorqueBox
 
Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015Rhebok, High Performance Rack Handler / Rubykaigi 2015
Rhebok, High Performance Rack Handler / Rubykaigi 2015
 
Joker 2015 - Валеев Тагир - Что же мы измеряем?
Joker 2015 - Валеев Тагир - Что же мы измеряем?Joker 2015 - Валеев Тагир - Что же мы измеряем?
Joker 2015 - Валеев Тагир - Что же мы измеряем?
 
Docker tips-for-java-developers
Docker tips-for-java-developersDocker tips-for-java-developers
Docker tips-for-java-developers
 

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
 
Акторы в 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
 
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
 
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
 
Dive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message ChainsDive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message Chains
Yauheni Akhotnikau
 
Dive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: DispatchersDive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: Dispatchers
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
 
Dive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message LimitsDive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message Limits
Yauheni Akhotnikau
 
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous InteractionDive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Yauheni Akhotnikau
 
Dive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: TimersDive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: Timers
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
 

More from Yauheni Akhotnikau (20)

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...
 
Акторы в 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
 
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
 
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++ что, зачем и как?
 
Dive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message ChainsDive into SObjectizer 5.5. Ninth Part: Message Chains
Dive into SObjectizer 5.5. Ninth Part: Message Chains
 
Dive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: DispatchersDive into SObjectizer 5.5. Eighth Part: Dispatchers
Dive into SObjectizer 5.5. Eighth Part: Dispatchers
 
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
 
Dive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message LimitsDive into SObjectizer 5.5. Seventh part: Message Limits
Dive into SObjectizer 5.5. Seventh part: Message Limits
 
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous InteractionDive into SObjectizer-5.5. Sixth part: Synchronous Interaction
Dive into SObjectizer-5.5. Sixth part: Synchronous Interaction
 
Dive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: TimersDive into SObjectizer 5.5. Fifth part: Timers
Dive into SObjectizer 5.5. Fifth part: Timers
 
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
 

Recently uploaded

Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...
Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...
Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...
Medical / Health Care (+971588192166) Mifepristone and Misoprostol tablets 200mg
 
Cultural Shifts: Embracing DevOps for Organizational Transformation
Cultural Shifts: Embracing DevOps for Organizational TransformationCultural Shifts: Embracing DevOps for Organizational Transformation
Cultural Shifts: Embracing DevOps for Organizational Transformation
Mindfire Solution
 
dachnug51 - HCL Sametime 12 as a Software Appliance.pdf
dachnug51 - HCL Sametime 12 as a Software Appliance.pdfdachnug51 - HCL Sametime 12 as a Software Appliance.pdf
dachnug51 - HCL Sametime 12 as a Software Appliance.pdf
DNUG e.V.
 
Overview of ERP - Mechlin Technologies.pptx
Overview of ERP - Mechlin Technologies.pptxOverview of ERP - Mechlin Technologies.pptx
Overview of ERP - Mechlin Technologies.pptx
Mitchell Marsh
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
karim wahed
 
Leading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptxLeading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptx
taskroupseo
 
How we built TryBoxLang in under 48 hours
How we built TryBoxLang in under 48 hoursHow we built TryBoxLang in under 48 hours
How we built TryBoxLang in under 48 hours
Ortus Solutions, Corp
 
Break data silos with real-time connectivity using Confluent Cloud Connectors
Break data silos with real-time connectivity using Confluent Cloud ConnectorsBreak data silos with real-time connectivity using Confluent Cloud Connectors
Break data silos with real-time connectivity using Confluent Cloud Connectors
confluent
 
Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.
shivamt017
 
FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)
FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)
FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)
Roshan Dwivedi
 
introduction of Ansys software and basic and advance knowledge of modelling s...
introduction of Ansys software and basic and advance knowledge of modelling s...introduction of Ansys software and basic and advance knowledge of modelling s...
introduction of Ansys software and basic and advance knowledge of modelling s...
sachin chaurasia
 
ENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentationENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentation
sofiafernandezon
 
CViewSurvey Digitech Pvt Ltd that works on a proven C.A.A.G. model.
CViewSurvey Digitech Pvt Ltd that  works on a proven C.A.A.G. model.CViewSurvey Digitech Pvt Ltd that  works on a proven C.A.A.G. model.
CViewSurvey Digitech Pvt Ltd that works on a proven C.A.A.G. model.
bhatinidhi2001
 
Responsibilities of Fleet Managers and How TrackoBit Can Assist.pdf
Responsibilities of Fleet Managers and How TrackoBit Can Assist.pdfResponsibilities of Fleet Managers and How TrackoBit Can Assist.pdf
Responsibilities of Fleet Managers and How TrackoBit Can Assist.pdf
Trackobit
 
Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)
miso_uam
 
dachnug51 - All you ever wanted to know about domino licensing.pdf
dachnug51 - All you ever wanted to know about domino licensing.pdfdachnug51 - All you ever wanted to know about domino licensing.pdf
dachnug51 - All you ever wanted to know about domino licensing.pdf
DNUG e.V.
 
dachnug51 - Whats new in domino 14 .pdf
dachnug51 - Whats new in domino 14  .pdfdachnug51 - Whats new in domino 14  .pdf
dachnug51 - Whats new in domino 14 .pdf
DNUG e.V.
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdfAWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
karim wahed
 
Migrate your Infrastructure to the AWS Cloud
Migrate your Infrastructure to the AWS CloudMigrate your Infrastructure to the AWS Cloud
Migrate your Infrastructure to the AWS Cloud
Ortus Solutions, Corp
 
MVP Mobile Application - Codearrest.pptx
MVP Mobile Application - Codearrest.pptxMVP Mobile Application - Codearrest.pptx
MVP Mobile Application - Codearrest.pptx
Mitchell Marsh
 

Recently uploaded (20)

Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...
Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...Abortion pills in Fujairah *((+971588192166*)☎️)¥) **Effective Abortion Pills...
Abortion pills in Fujairah *((+971588192166*)☎���)¥) **Effective Abortion Pills...
 
Cultural Shifts: Embracing DevOps for Organizational Transformation
Cultural Shifts: Embracing DevOps for Organizational TransformationCultural Shifts: Embracing DevOps for Organizational Transformation
Cultural Shifts: Embracing DevOps for Organizational Transformation
 
dachnug51 - HCL Sametime 12 as a Software Appliance.pdf
dachnug51 - HCL Sametime 12 as a Software Appliance.pdfdachnug51 - HCL Sametime 12 as a Software Appliance.pdf
dachnug51 - HCL Sametime 12 as a Software Appliance.pdf
 
Overview of ERP - Mechlin Technologies.pptx
Overview of ERP - Mechlin Technologies.pptxOverview of ERP - Mechlin Technologies.pptx
Overview of ERP - Mechlin Technologies.pptx
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) Course Introducti...
 
Leading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptxLeading Project Management Tool Taskruop.pptx
Leading Project Management Tool Taskruop.pptx
 
How we built TryBoxLang in under 48 hours
How we built TryBoxLang in under 48 hoursHow we built TryBoxLang in under 48 hours
How we built TryBoxLang in under 48 hours
 
Break data silos with real-time connectivity using Confluent Cloud Connectors
Break data silos with real-time connectivity using Confluent Cloud ConnectorsBreak data silos with real-time connectivity using Confluent Cloud Connectors
Break data silos with real-time connectivity using Confluent Cloud Connectors
 
Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.Shivam Pandit working on Php Web Developer.
Shivam Pandit working on Php Web Developer.
 
FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)
FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)
FAST Channels: Explosive Growth Forecast 2024-2027 (Buckle Up!)
 
introduction of Ansys software and basic and advance knowledge of modelling s...
introduction of Ansys software and basic and advance knowledge of modelling s...introduction of Ansys software and basic and advance knowledge of modelling s...
introduction of Ansys software and basic and advance knowledge of modelling s...
 
ENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentationENISA Threat Landscape 2023 documentation
ENISA Threat Landscape 2023 documentation
 
CViewSurvey Digitech Pvt Ltd that works on a proven C.A.A.G. model.
CViewSurvey Digitech Pvt Ltd that  works on a proven C.A.A.G. model.CViewSurvey Digitech Pvt Ltd that  works on a proven C.A.A.G. model.
CViewSurvey Digitech Pvt Ltd that works on a proven C.A.A.G. model.
 
Responsibilities of Fleet Managers and How TrackoBit Can Assist.pdf
Responsibilities of Fleet Managers and How TrackoBit Can Assist.pdfResponsibilities of Fleet Managers and How TrackoBit Can Assist.pdf
Responsibilities of Fleet Managers and How TrackoBit Can Assist.pdf
 
Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)Software development... for all? (keynote at ICSOFT'2024)
Software development... for all? (keynote at ICSOFT'2024)
 
dachnug51 - All you ever wanted to know about domino licensing.pdf
dachnug51 - All you ever wanted to know about domino licensing.pdfdachnug51 - All you ever wanted to know about domino licensing.pdf
dachnug51 - All you ever wanted to know about domino licensing.pdf
 
dachnug51 - Whats new in domino 14 .pdf
dachnug51 - Whats new in domino 14  .pdfdachnug51 - Whats new in domino 14  .pdf
dachnug51 - Whats new in domino 14 .pdf
 
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdfAWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
AWS Cloud Practitioner Essentials (Second Edition) (Arabic) AWS Security .pdf
 
Migrate your Infrastructure to the AWS Cloud
Migrate your Infrastructure to the AWS CloudMigrate your Infrastructure to the AWS Cloud
Migrate your Infrastructure to the AWS Cloud
 
MVP Mobile Application - Codearrest.pptx
MVP Mobile Application - Codearrest.pptxMVP Mobile Application - Codearrest.pptx
MVP Mobile Application - Codearrest.pptx
 

Shrimp: A Rather Practical Example Of Application Development With RESTinio and SObjectizer

  • 2. A few words about us ● ● 2
  • 4. What is Shrimp? From 30000 feets 4
  • 5. Why Shrimp was created? ● ● ● 5
  • 6. But there is another reason 6
  • 7. We need to go deeper... 7
  • 8. What is Shrimp? Actually ● ● 8
  • 9. Shrimp in a simple example 9
  • 10. Shrimp in a simple example 10 $ curl -o test.webp "https://shrimp-demo.stiffstream.com/DSCF6555.jpg?op=resize&width=300&target-format=webp" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 41162 100 41162 0 0 41162 0 0:00:01 --:--:-- 0:00:01 151k $ ls -l *.webp -rw-rw-r-- 1 eao197 eao197 41162 сен 4 08:28 test.webp
  • 11. Shrimp in a simple example 11 $ curl -o test.webp "https://shrimp-demo.stiffstream.com/DSCF6555.jpg?op=resize&width=300&target-format=webp" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 41162 100 41162 0 0 41162 0 0:00:01 --:--:-- 0:00:01 151k $ ls -l *.webp -rw-rw-r-- 1 eao197 eao197 41162 сен 4 08:28 test.webp
  • 19. Shrimp's internals in a few words ● ● ● 19
  • 20. A picture is worth a thousand words 20
  • 21. What is used inside Shrimp? 21
  • 26. External Asio context // ASIO io_context must outlive sobjectizer. asio::io_context asio_io_ctx; // Launch SObjectizer and wait while balancer will be started. ... so_5::wrapped_env_t sobj{ [&]( so_5::environment_t & env ) {...}, [&]( so_5::environment_params_t & params ) {...} }; // Now we can launch HTTP-server. restinio::run( asio_io_ctx, shrimp::make_http_server_settings(...) ); 26
  • 27. External Asio context // ASIO io_context must outlive sobjectizer. asio::io_context asio_io_ctx; // Launch SObjectizer and wait while balancer will be started. ... so_5::wrapped_env_t sobj{ [&]( so_5::environment_t & env ) {...}, [&]( so_5::environment_params_t & params ) {...} }; // Now we can launch HTTP-server. restinio::run( asio_io_ctx, shrimp::make_http_server_settings(...) ); 27 Asio's io_context object is created.
  • 28. External Asio context // ASIO io_context must outlive sobjectizer. asio::io_context asio_io_ctx; // Launch SObjectizer and wait while balancer will be started. ... so_5::wrapped_env_t sobj{ [&]( so_5::environment_t & env ) {...}, [&]( so_5::environment_params_t & params ) {...} }; // Now we can launch HTTP-server. restinio::run( asio_io_ctx, shrimp::make_http_server_settings(...) ); 28 SObjectizer is started here. SObjectizer will be stopped and destroyed before destruction of io_context.
  • 29. External Asio context // ASIO io_context must outlive sobjectizer. asio::io_context asio_io_ctx; // Launch SObjectizer and wait while balancer will be started. ... so_5::wrapped_env_t sobj{ [&]( so_5::environment_t & env ) {...}, [&]( so_5::environment_params_t & params ) {...} }; // Now we can launch HTTP-server. restinio::run( asio_io_ctx, shrimp::make_http_server_settings(...) ); 29 RESTinio is started here. restinio::run() returns only after shutdown of HTTP-server.
  • 31. Wrapper around spdlog's logger class http_server_logger_t { public: http_server_logger_t( std::shared_ptr<spdlog::logger> logger ) : m_logger{std::move(logger)} {} template<typename Builder> void trace( Builder && msg_builder ) { log_if_enabled( spdlog::level::trace, std::forward<Builder>(msg_builder) ); } template<typename Builder> void info( Builder && msg_builder ) { log_if_enabled( spdlog::level::info, std::forward<Builder>(msg_builder) ); } ... private: template<typename Builder> void log_if_enabled( spdlog::level::level_enum lv, Builder && msg_builder ) { if( m_logger->should_log(lv) ) { m_logger->log( lv, msg_builder() ); } } std::shared_ptr<spdlog::logger> m_logger; }; 31
  • 32. Tie our wrapper type with RESTinio's traits struct http_server_traits_t : public restinio::default_traits_t { using logger_t = http_server_logger_t; using request_handler_t = http_req_router_t; }; 32
  • 33. Tie our wrapper type with RESTinio's traits struct http_server_traits_t : public restinio::default_traits_t { using logger_t = http_server_logger_t; using request_handler_t = http_req_router_t; }; 33 Now RESTinio server with this traits will use instance of http_server_logger_t for logging.
  • 34. Instantiation of our wrapper [[nodiscard]] inline auto make_http_server_settings( unsigned int thread_pool_size, const app_params_t & params, std::shared_ptr<spdlog::logger> logger, so_5::mbox_t req_handler_mbox ) { ... return restinio::on_thread_pool< http_server_traits_t >( thread_pool_size ) .port( http_srv_params.m_port ) .protocol( ip_protocol(http_srv_params.m_ip_version) ) .address( http_srv_params.m_address ) .handle_request_timeout( std::chrono::seconds(60) ) .write_http_response_timelimit( std::chrono::seconds(60) ) .logger( std::move(logger) ) .request_handler( make_router( params, req_handler_mbox ) ); } 34
  • 35. Instantiation of our wrapper [[nodiscard]] inline auto make_http_server_settings( unsigned int thread_pool_size, const app_params_t & params, std::shared_ptr<spdlog::logger> logger, so_5::mbox_t req_handler_mbox ) { ... return restinio::on_thread_pool< http_server_traits_t >( thread_pool_size ) .port( http_srv_params.m_port ) .protocol( ip_protocol(http_srv_params.m_ip_version) ) .address( http_srv_params.m_address ) .handle_request_timeout( std::chrono::seconds(60) ) .write_http_response_timelimit( std::chrono::seconds(60) ) .logger( std::move(logger) ) .request_handler( make_router( params, req_handler_mbox ) ); } 35
  • 36. Instantiation of our wrapper [[nodiscard]] inline auto make_http_server_settings( unsigned int thread_pool_size, const app_params_t & params, std::shared_ptr<spdlog::logger> logger, so_5::mbox_t req_handler_mbox ) { ... return restinio::on_thread_pool< http_server_traits_t >( thread_pool_size ) .port( http_srv_params.m_port ) .protocol( ip_protocol(http_srv_params.m_ip_version) ) .address( http_srv_params.m_address ) .handle_request_timeout( std::chrono::seconds(60) ) .write_http_response_timelimit( std::chrono::seconds(60) ) .logger( std::move(logger) ) .request_handler( make_router( params, req_handler_mbox ) ); } 36 Object of type http_server_traits_t::logger_t (aka http_server_logger_t) will be created here. Spdlog's logger will be passed to the constructor of that object.
  • 37. Log example (with --restinio-tracing -l trace) 37
  • 39. ExpressJS-like routing using http_req_router_t = restinio::router::express_router_t< restinio::router::pcre_regex_engine_t< restinio::router::pcre_traits_t< // Max capture groups for regex. 5 > > >; 39
  • 40. ExpressJS-like routing using http_req_router_t = restinio::router::express_router_t< restinio::router::pcre_regex_engine_t< restinio::router::pcre_traits_t< // Max capture groups for regex. 5 > > >; 40 Express router can use different engines. There are engines based on std::regex, Boost.Regex and PCRE/PCRE2. A PCRE-based engine is used here.
  • 41. ExpressJS-like routing struct http_server_traits_t : public restinio::default_traits_t { using logger_t = http_server_logger_t; using request_handler_t = http_req_router_t; }; 41
  • 42. ExpressJS-like routing void add_transform_op_handler( const app_params_t & app_params, http_req_router_t & router, so_5::mbox_t req_handler_mbox ) { router.http_get( R"(/:path(.*).:ext(.{3,4}))", restinio::path2regex::options_t{}.strict( true ), [req_handler_mbox, &app_params]( auto req, auto params ) {...} ); } 42
  • 43. ExpressJS-like routing void add_transform_op_handler( const app_params_t & app_params, http_req_router_t & router, so_5::mbox_t req_handler_mbox ) { router.http_get( R"(/:path(.*).:ext(.{3,4}))", restinio::path2regex::options_t{}.strict( true ), [req_handler_mbox, &app_params]( auto req, auto params ) {...} ); } 43 A route with two arguments ('path' and 'ext') is defined here.
  • 44. sendfile for serving original files sendfile() TransmitFile() 44
  • 45. sendfile for serving original files [[nodiscard]] restinio::request_handling_status_t serve_as_regular_file(const std::string & root_dir, restinio::request_handle_t req, image_format_t image_format) { const auto full_path = make_full_path( root_dir, req->header().path() ); try { auto sf = restinio::sendfile( full_path ); const auto last_modified = sf.meta().last_modified_at(); auto resp = req->create_response(); return set_common_header_fields_for_image_resp( last_modified, resp ) .append_header( restinio::http_field::content_type, image_content_type_from_img_format(image_format) ) .append_header( restinio::http_header_field_t{ http_header::shrimp_image_src_hf(), image_src_to_str( http_header::image_src_t::sendfile ) } ) .set_body( std::move(sf) ) .done(); } catch(...) { } return do_404_response( std::move( req ) ); } 45
  • 46. sendfile for serving original files [[nodiscard]] restinio::request_handling_status_t serve_as_regular_file(const std::string & root_dir, restinio::request_handle_t req, image_format_t image_format) { const auto full_path = make_full_path( root_dir, req->header().path() ); try { auto sf = restinio::sendfile( full_path ); const auto last_modified = sf.meta().last_modified_at(); auto resp = req->create_response(); return set_common_header_fields_for_image_resp( last_modified, resp ) .append_header( restinio::http_field::content_type, image_content_type_from_img_format(image_format) ) .append_header( restinio::http_header_field_t{ http_header::shrimp_image_src_hf(), image_src_to_str( http_header::image_src_t::sendfile ) } ) .set_body( std::move(sf) ) .done(); } catch(...) { } return do_404_response( std::move( req ) ); } 46 sendfile operation is defined here.
  • 47. sendfile for serving original files [[nodiscard]] restinio::request_handling_status_t serve_as_regular_file(const std::string & root_dir, restinio::request_handle_t req, image_format_t image_format) { const auto full_path = make_full_path( root_dir, req->header().path() ); try { auto sf = restinio::sendfile( full_path ); const auto last_modified = sf.meta().last_modified_at(); auto resp = req->create_response(); return set_common_header_fields_for_image_resp( last_modified, resp ) .append_header( restinio::http_field::content_type, image_content_type_from_img_format(image_format) ) .append_header( restinio::http_header_field_t{ http_header::shrimp_image_src_hf(), image_src_to_str( http_header::image_src_t::sendfile ) } ) .set_body( std::move(sf) ) .done(); } catch(...) { } return do_404_response( std::move( req ) ); } 47 sendfile operation is used here for sending file's content as response's body.
  • 48. The next big topic 48
  • 52. transformer agent class a_transformer_t final : public so_5::agent_t { public: struct resize_request_t final : public so_5::message_t {...}; a_transformer_t(context_t ctx, std::shared_ptr<spdlog::logger> logger, storage_params_t cfg); void so_define_agent() override { so_subscribe_self().event( &a_transformer_t::on_resize_request ); } private: ... on_resize_request(mutable_mhood_t<resize_request_t> cmd); ... }; 52
  • 53. transformer agent class a_transformer_t final : public so_5::agent_t { public: struct resize_request_t final : public so_5::message_t {...}; a_transformer_t(context_t ctx, std::shared_ptr<spdlog::logger> logger, storage_params_t cfg); void so_define_agent() override { so_subscribe_self().event( &a_transformer_t::on_resize_request ); } private: ... on_resize_request(mutable_mhood_t<resize_request_t> cmd); ... }; 53 Message to be handled.
  • 54. transformer agent class a_transformer_t final : public so_5::agent_t { public: struct resize_request_t final : public so_5::message_t {...}; a_transformer_t(context_t ctx, std::shared_ptr<spdlog::logger> logger, storage_params_t cfg); void so_define_agent() override { so_subscribe_self().event( &a_transformer_t::on_resize_request ); } private: ... on_resize_request(mutable_mhood_t<resize_request_t> cmd); ... }; 54 Subscription to the message. When message resize_request_t arrives the on_resize_request() method will be called. Type of message to be subscribed is deduced from handler's prototype.
  • 56. transform_manager agent (1) class a_transform_manager_t final : public so_5::agent_t { public: struct resize_request_t final : public so_5::message_t {...}; struct resize_result_t final : public so_5::message_t {...}; struct delete_cache_request_t final : public so_5::message_t {...}; a_transform_manager_t(context_t ctx, std::shared_ptr<spdlog::logger> logger); void so_define_agent() override; void so_evt_start() override; ... 56
  • 57. transform_manager agent (1) class a_transform_manager_t final : public so_5::agent_t { public: struct resize_request_t final : public so_5::message_t {...}; struct resize_result_t final : public so_5::message_t {...}; struct delete_cache_request_t final : public so_5::message_t {...}; a_transform_manager_t(context_t ctx, std::shared_ptr<spdlog::logger> logger); void so_define_agent() override; void so_evt_start() override; ... 57 Those are "public" messages. They are sent to transform_manager by external entities: ● resize_request_t and delete_cache_request_t are sent by HTTP-server; ● resize_result_t is sent by transformer agent.
  • 58. transform_manager agent (2) private : struct negative_delete_cache_response_t : public so_5::message_t {...}; struct clear_cache_t final : public so_5::signal_t {}; struct check_pending_requests_t final : public so_5::signal_t {}; ... void on_resize_request(mutable_mhood_t<resize_request_t> cmd); void on_resize_result(mutable_mhood_t<resize_result_t> cmd); void on_delete_cache_request(mutable_mhood_t<delete_cache_request_t> cmd); void on_negative_delete_cache_response( mutable_mhood_t<negative_delete_cache_response_t> cmd); void on_clear_cache(mhood_t<clear_cache_t>); void on_check_pending_requests(mhood_t<check_pending_requests_t>); ... }; 58
  • 59. transform_manager agent (2) private : struct negative_delete_cache_response_t : public so_5::message_t {...}; struct clear_cache_t final : public so_5::signal_t {}; struct check_pending_requests_t final : public so_5::signal_t {}; ... void on_resize_request(mutable_mhood_t<resize_request_t> cmd); void on_resize_result(mutable_mhood_t<resize_result_t> cmd); void on_delete_cache_request(mutable_mhood_t<delete_cache_request_t> cmd); void on_negative_delete_cache_response( mutable_mhood_t<negative_delete_cache_response_t> cmd); void on_clear_cache(mhood_t<clear_cache_t>); void on_check_pending_requests(mhood_t<check_pending_requests_t>); ... }; 59 Those are "private" message and signals. transform_manager sends them to itself.
  • 60. transform_manager agent (3) void a_transform_manager_t::so_define_agent() { so_subscribe_self() .event( &a_transform_manager_t::on_resize_request ) .event( &a_transform_manager_t::on_resize_result ) .event( &a_transform_manager_t::on_delete_cache_request ) .event( &a_transform_manager_t::on_negative_delete_cache_response ) .event( &a_transform_manager_t::on_clear_cache ) .event( &a_transform_manager_t::on_check_pending_requests ); } 60
  • 62. Basic working scheme a_transform_manager_t::resize_request_t 62 void handle_resize_op_request( const so_5::mbox_t & req_handler_mbox, image_format_t image_format, const restinio::query_string_params_t & qp, restinio::request_handle_t req ) { try_to_handle_request( [&]{ auto op_params = transform::resize_params_t::make( restinio::opt_value< std::uint32_t >( qp, "width" ), restinio::opt_value< std::uint32_t >( qp, "height" ), restinio::opt_value< std::uint32_t >( qp, "max" ) ); transform::resize_params_constraints_t{}.check( op_params ); std::string image_path{ req->header().path() }; so_5::send< so_5::mutable_msg<a_transform_manager_t::resize_request_t> >( req_handler_mbox, std::move(req), std::move(image_path), image_format, op_params ); }, req ); }
  • 64. Basic working scheme a_transformer_t::resize_request_t 64 void a_transform_manager_t::try_initiate_pending_requests_processing() { while( !m_free_workers.empty() && !m_pending_requests.empty() ) { auto atoken = m_pending_requests.oldest().value(); const auto key = atoken.key(); m_pending_requests.extract_values_for_key( std::move(atoken), [&]( auto && value ) { m_inprogress_requests.insert( transform::resize_request_key_t{key}, std::move(value) ); } ); auto worker = std::move(m_free_workers.top()); m_free_workers.pop(); m_logger->trace("initiate processing of a request; request_key={}, worker_mbox={}", key, worker->id()); so_5::send< so_5::mutable_msg<a_transformer_t::resize_request_t> >(worker, key, so_direct_mbox()); } }
  • 66. Basic working scheme a_transform_manager_t::resize_result_t 66 void a_transformer_t::on_resize_request( mutable_mhood_t<resize_request_t> cmd) { auto result = handle_resize_request( cmd->m_key ); so_5::send< so_5::mutable_msg<a_transform_manager_t::resize_result_t> >( cmd->m_reply_to, so_direct_mbox(), std::move(cmd->m_key), std::move(result) ); }
  • 68. Basic working scheme 68 void a_transform_manager_t::on_resize_result( mutable_mhood_t<resize_result_t> cmd ) { m_logger->trace( "resize_result received; request_key={}, worker_mbox={}", cmd->m_key, cmd->m_worker->id() ); m_free_workers.push( std::move(cmd->m_worker) ); try_initiate_pending_requests_processing(); auto key = std::move(cmd->m_key); auto requests = extract_inprogress_requests( std::move(m_inprogress_requests.find_first_for_key( key ).value()) ); std::visit( variant_visitor{ [&]( successful_resize_t & result ) { on_successful_resize( std::move(key), result, std::move(requests) ); }, [&]( failed_resize_t & result ) { on_failed_resize( std::move(key), result, std::move(requests) ); } }, cmd->m_result ); }
  • 69. Basic working scheme 69 void a_transform_manager_t::on_resize_result( mutable_mhood_t<resize_result_t> cmd ) { m_logger->trace( "resize_result received; request_key={}, worker_mbox={}", cmd->m_key, cmd->m_worker->id() ); m_free_workers.push( std::move(cmd->m_worker) ); try_initiate_pending_requests_processing(); auto key = std::move(cmd->m_key); auto requests = extract_inprogress_requests( std::move(m_inprogress_requests.find_first_for_key( key ).value()) ); std::visit( variant_visitor{ [&]( successful_resize_t & result ) { on_successful_resize( std::move(key), result, std::move(requests) ); }, [&]( failed_resize_t & result ) { on_failed_resize( std::move(key), result, std::move(requests) ); } }, cmd->m_result ); } void a_transform_manager_t::on_failed_resize( transform::resize_request_key_t key, failed_resize_t & result, original_request_container_t requests ) { m_logger->warn( "failed resize; request_key={}, reason={}", key, result.m_reason ); for( auto & rq : requests ) { m_logger->trace( "sending negative response back; request_key={}, connection_id={}", key, rq->m_http_req->connection_id() ); do_404_response( std::move(rq->m_http_req) ); } }
  • 70. Providing work threads to agents 70
  • 71. Providing work threads to agents (1) [[nodiscard]] so_5::mbox_t create_agents( spdlog::sink_ptr logger_sink, const shrimp::app_params_t & app_params, so_5::environment_t & env, unsigned int worker_threads_count ) { using namespace shrimp; using namespace so_5::disp::one_thread; // For create_private_disp. so_5::mbox_t manager_mbox; env.introduce_coop([&]( so_5::coop_t & coop ) { auto manager = coop.make_agent_with_binder< a_transform_manager_t >( create_private_disp( env, "manager" )->binder(), make_logger( "manager", logger_sink ) ); manager_mbox = manager->so_direct_mbox(); 71
  • 72. Providing work threads to agents (1) [[nodiscard]] so_5::mbox_t create_agents( spdlog::sink_ptr logger_sink, const shrimp::app_params_t & app_params, so_5::environment_t & env, unsigned int worker_threads_count ) { using namespace shrimp; using namespace so_5::disp::one_thread; // For create_private_disp. so_5::mbox_t manager_mbox; env.introduce_coop([&]( so_5::coop_t & coop ) { auto manager = coop.make_agent_with_binder< a_transform_manager_t >( create_private_disp( env, "manager" )->binder(), make_logger( "manager", logger_sink ) ); manager_mbox = manager->so_direct_mbox(); 72 transform_manager agent is created and is bound to separate one_thread dispatcher. It means that transform_manager will have its own work thread.
  • 73. Providing work threads to agents (2) // Every worker will work on its own private dispatcher. for( unsigned int worker{}; worker < worker_threads_count; ++worker ) { const auto worker_name = fmt::format( "worker_{}", worker ); auto transformer = coop.make_agent_with_binder< a_transformer_t >( create_private_disp( env, worker_name )->binder(), make_logger( worker_name, logger_sink ), app_params.m_storage ); manager->add_worker( transformer->so_direct_mbox() ); } } ); return manager_mbox; } 73
  • 74. Providing work threads to agents (2) // Every worker will work on its own private dispatcher. for( unsigned int worker{}; worker < worker_threads_count; ++worker ) { const auto worker_name = fmt::format( "worker_{}", worker ); auto transformer = coop.make_agent_with_binder< a_transformer_t >( create_private_disp( env, worker_name )->binder(), make_logger( worker_name, logger_sink ), app_params.m_storage ); manager->add_worker( transformer->so_direct_mbox() ); } } ); return manager_mbox; } 74 The same is for every transformer agent.
  • 75. And now the end is near... 75
  • 76. The results of the experiment 76
  • 77. It's not a 10-lines HelloWorld 77
  • 78. It's not a 10-lines HelloWorld #include <restinio/all.hpp> int main() { restinio::run( restinio::on_this_thread<>() .port(8080) .address("localhost") .request_handler([](auto req) { return req->create_response().set_body("Hello, World!").done(); })); return 0; } 78
  • 79. It's not a 10-lines HelloWorld #include <restinio/all.hpp> int main() { restinio::run( restinio::on_this_thread<>() .port(8080) .address("localhost") .request_handler([](auto req) { return req->create_response().set_body("Hello, World!").done(); })); return 0; } 79
  • 80. It's not a 10-lines HelloWorld #include <restinio/all.hpp> int main() { restinio::run( restinio::on_this_thread<>() .port(8080) .address("localhost") .request_handler([](auto req) { return req->create_response().set_body("Hello, World!").done(); })); return 0; } 80
  • 81. New ideas for implementation 81
  • 82. We are open for new ideas... 82
  • 83. References at one place 83