odyssey/INTERNALS.md

97 lines
4.0 KiB
Markdown
Raw Normal View History

2017-07-17 10:32:14 +00:00
### Odissey architecture and internals
2017-07-17 10:32:14 +00:00
2017-07-17 10:38:28 +00:00
Odissey heavily depends on two libraries, which were originally created during its
development: Machinarium and Shapito.
2017-07-17 10:32:14 +00:00
#### Machinarium
2017-07-17 10:32:14 +00:00
2017-07-18 10:11:59 +00:00
Machinarium extensively used for organization of multi-thread processing, cooperative multi-tasking
and networking IO. All Odissey threads are run in context of machinarium `machines` -
pthreads with coroutine schedulers placed on top of `epoll(2)` event loop.
2017-07-17 10:32:14 +00:00
2017-07-18 10:11:59 +00:00
Odissey does not directly use or create multi-tasking primitives such as OS threads and mutexes.
All synchronization is done using message passing and transparently handled by machinarium.
2017-07-17 10:32:14 +00:00
2017-07-17 10:38:28 +00:00
Repository: [github/machinarium](https://github.yandex-team.ru/pmwkaa/machinarium)
#### Shapito
2017-07-17 10:32:14 +00:00
Shapito provides resizable buffers (streams) and methods for constructing, reading and validating
2017-07-18 10:11:59 +00:00
PostgreSQL protocol requests. By design, all PostgreSQL specific details should be provided by
Shapito library.
2017-07-17 10:38:28 +00:00
Repository: [github/shapito](https://github.yandex-team.ru/pmwkaa/shapito).
2017-07-18 13:35:31 +00:00
#### Core components
2017-07-19 09:47:41 +00:00
```
2017-07-18 15:03:29 +00:00
main()
.----------.
| instance |
2017-07-19 09:47:41 +00:00
thread '----------'
.--------. .------------.
| pooler | | relay_pool |
'--------' '------------'
.--------. .---------. .--------. .--------.
| router | | servers | | relay0 | ... | relayN |
'--------' '---------' '--------' '--------'
.---------. .----------. thread thread
| console | | periodic |
'---------' '----------'
```
2017-07-18 13:35:31 +00:00
#### Instance
2017-07-18 14:06:53 +00:00
Application entry point.
2017-07-18 14:27:40 +00:00
Handle initialization. Read configuration file, prepare loggers.
2017-07-18 14:06:53 +00:00
Run pooler and relay\_pool threads.
2017-07-18 14:27:40 +00:00
[sources/instance.h](sources/instance.h), [sources/instance.c](sources/instance.c)
2017-07-18 14:06:53 +00:00
#### Pooler
2017-07-18 14:06:53 +00:00
Start router, periodic and console subsystems.
2017-07-18 14:27:40 +00:00
Create listen server one for each resolved address. Each listen server runs inside own coroutine.
Server coroutine mostly waits on `machine_accept()`.
On incoming connection, new client context is created and notification message is sent to next
2017-07-18 15:03:29 +00:00
relay worker using `relaypool_feed()`. Client IO context is detached from pooler `epoll(2)` context.
2017-07-18 14:06:53 +00:00
Handle signals using `machine_signal_wait()`. On SIGHUP: do versional config reload, add new databases
and obsolete old ones. On SIGINT: call `exit()`. Other threads are blocked from receiving signals.
2017-07-18 14:27:40 +00:00
[sources/pooler.h](sources/pooler.h), [sources/pooler.c](sources/pooler.c)
2017-07-18 14:06:53 +00:00
#### Router
2017-07-18 14:06:53 +00:00
2017-07-19 09:47:41 +00:00
Handle client registration and routing requests. Do client-to-server attachment and detachment.
Ensure connection limits and client pool queueing. Handle implicit `Cancel` client request, since access
to server pool is required to match a client key.
2017-07-18 14:27:40 +00:00
2017-07-18 15:03:29 +00:00
Router works in request-reply manner: client (from relay thread) sends a request message to
router and waits for reply. Could be a potential hot spot (not an issue at the moment).
2017-07-18 14:06:53 +00:00
2017-07-18 14:27:40 +00:00
[sources/router.h](sources/router.h), [sources/router.c](sources/router.c)
2017-07-18 14:06:53 +00:00
#### Periodic
2017-07-18 14:06:53 +00:00
2017-07-19 09:47:41 +00:00
Do periodic service tasks, like idle server connection expiration and
2017-07-18 14:27:40 +00:00
database scheme obsoletion.
2017-07-18 14:06:53 +00:00
2017-07-18 14:27:40 +00:00
[sources/periodic.h](sources/periodic.h), [sources/periodic.c](sources/periodic.c)
2017-07-18 14:06:53 +00:00
#### Relay and Relay pool
Relay machine (thread) waits on incoming connection notification queue. On new connection event,
create new frontend coroutine and handle client (frontend) lifecycle. Each relay thread can host
thousands of client coroutines.
2017-07-18 14:06:53 +00:00
Relay pool is responsible for maintaining a worker thread pool. Threads are machinarium machines,
created using `machine_create()`.
2017-07-18 14:06:53 +00:00
2017-07-18 14:27:40 +00:00
[sources/relay.h](sources/relay.h), [sources/relay.c](sources/relay.c),
[sources/relay_pool.h](sources/relay_pool.h), [sources/relay_pool.c](sources/relay_pool.c)