Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New mode for SuperServer run [CORE5912] #6170

Closed
firebird-automations opened this issue Sep 15, 2018 · 2 comments
Closed

New mode for SuperServer run [CORE5912] #6170

firebird-automations opened this issue Sep 15, 2018 · 2 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: Basil A. Sidorov (basid)

Note: my native lang is Russian, but I can read "simple English".

Proposal.
Add new mode for run Firebird 3+ SuperServer, called (for example) "MultiServer".

In this mode Firebird server should work as two part - single "Dispatcher" and many "Engine".

Each Engine work in separate OS process and serve only one database (but all users on that database).
Dispatcher accept network connections, extract database name or alias from parameter block and redirect (whole) connection stream to (some) Engine.
Dispatcher may pre-run Engine based on content aliases.conf (databases.conf) and offer gracefull Engine shutdown on change content aliases./databases.conf

Goal.
Make possible isolation whole SuperServer from craches on single database, separate metadata cache, better localization buffer cache and better handle databases with different parameters and load type.

Disadvantage.
Additional work, grow resource usage.

Suggested (cross-platform) implementation based on local TCP-connections. Long read.

Command line:
"fbserver -0x0000 ..." run dispatcher (dots are omitted arguments).
"fbserver -0xNUMBER [CONFIG]" - run engine (square brackets - optional arguments).
NUMBER is (strictly) four HEX-digits for Dispathcer communation port.
CONFIG, if specified, coded as UTF-8 string and use instead firebird.conf.

Protocol:
Distpatcher and Engine communicate via simple text protocol with (short) fixed-length message (eight octets).
Message is UTF-8 string in format '0x#⁠#⁠#⁠#⁠CRLF', where: '0x' - fixed prefix, #⁠#⁠#⁠#⁠ - four HEX-digit, CRLF - fixed suffix (canonical EOL: two octet - 0x0D and 0x0A in that order).

Dispatcher send to Engine message with port number of listening socket for each client steam.
Engine informs Dispatcher from wich ports Engine can be make connections. Not pair "Dispath:Engine" - simply (unordered) set of engine-side ports numbers.

Dispatcher and Engine use only localhost and port numbers, assigned by IP-stack.
Dispatcher should check engine-side PID (local) connection and close "aliens".
Engine should reject client stream from Dispatcher, if database name/alias differ from previous processed streams.

Long (and possible inaccurate) description:
Dispatcher request from OS listening socket (localhost:0).
On succes, Dispatcher remember port, which OS assign for this socket and use that port number for communicate with all Engine.

On start, Engine parse command line for communication port and CONFIG (if specified). Engine parse CONFIG (or firebird.conf) and so on.
After initial setup, Engine make connection on Dispatcher communication port, write "greeting" message (0x0000CRLF), call flush() and go into wait state.

On fatal error of initial setup, Engine connect to Dispatcher and immediately call "shutdown output" on socket. After read EOF from Dispatcher, Engine call "shutdown input", make cleanup and exit with (some) error code.
If no response from Dispatcher within reasonable time (about five minutes), Engine call "shutdown socket", cleanup and exit with error.
If network call is impossible or unsuccessfull - Engine simlpy cleanup and exit with error.

After receive connection and check engine-side PID, Dispatcher or close "aliens" or read "greeting".
Dispatcher write "confirmation" message (0x0000CRLF), call flush() and place "Control Channel" into communication pool.

On very first (remote) client connection, Dispatcher peek database name/alias from parameter block, select (some) "Control Channel" from communication pool and create "Data Channel".
For "Data Channel" Dispatcher request from OS listening socket (localhost:0). On success, Dispather send message to Engine with port number, assigned OS for that socket.
Dispatcher may write several message and send whole set by single flush() call.

Engine bind socket with "localhost:Dispatcher-DataPort / localhost:0". On success, Engine send info message with new port number to Dispatcher.
Engine may write several message and send it by single flush() call, but may not make connection with "new" engine-side port(s) before return from flush() call.

If, after initial greeting/confirmation message exchange, Dispatcher or Engine send again message with zero port number (0x0000CRLF) - it is flag for gracefull shutdown on service (that) database/Engine.

In gracefull shutdown state, Dispatcher should reject new client connections for database, but should transfer data on existing (client) connections and (Engine) "Data Channels".

After disconnect (in any way) all clients, Engine should call "shutdown output" on sockets of "Data Channels".
After read EOF from Dispatcher, Engine should call "shutdown input" and make resource cleanup.
If all client stream closed (in any way), Engine may gracefully close "Control Channel" end exit.
If gracefull shutdown requested by Dispatcher, Engine must gracefully close "Control Channel" and exit.

@firebird-automations
Copy link
Collaborator Author

Commented by: @livius2

You can install multiple servers already and you decide which server work with which database.

I see some difference:
1. one tcp port vs multiple tcp port
2. maybe one firebird.conf vs multiple firebird.conf
3. one user database vs multiple user database

@basid-irk
Copy link

Full redesign required - please close.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants