[server-dev] [RFC] Interactive transactions in IProto

Konstantin Osipov kostja at tarantool.org
Wed Nov 14 18:25:30 MSK 2018


* Vladimir Davydov <vdavydov.dev at gmail.com> [18/11/13 20:51]:
>  6. If IPROTO_STREAM_ID is unset (0), everything works as before, i.e.
>     no transaction preservation or request serialization will occur.

I think this is a bit confusing. Logically they all must belong to
stream id 0, but suddenly they all belong to (internally) distinct
streams. What if I do begin on the client without an assigned
stream id? Will I have a stream created automatically? What if I
do a commit for a non-existent stream id? 

> The net.box API will look like this:
> 
>   c = net_box.connect(...)
>   s = c:make_stream(stream_id)
>   s:call(...)
> 
> A net.box stream instance will be a wrapper around the connection it was
> created for. It will have all the same methods as the connection itself,
> but all requests sent on its behalf will have the stream id attached.

This is nice.

> ** Questions **
> 
> Should we limit the number of streams somehow? I don't think so, at
> least not right now, because streams are completely user controlled,
> like iproto connections.
> 

Definitely, it should be a global limit, a new box.cfg setting (as
much as I hate settings there is no waywe can do away without it
here afaiu).

> How to close a stream so that the corresponding stream object is
> destroyed on the server? Do we need to bother at all? May be dropping
> all streams along with a connection would be enough?

No, it's definitely not enough. We need to think about denial of
service attacks and hogging all server memory by creating too many
streams. This is especially important since automatic streams
(those that are created if stream id is not set) will also take
resources. Perhaps wee should forbid interactive transactions in
stream id 0, this would at least be safe.

Please also state explicitly what happens with open transactions
in a stream when a connection is closed. And yes, I presume ppl
will ask for ways to control the stream so we better think right
now what these ways could be (even if we decide to not implement
them at once).

> Should we avoid a fiber_call() when queueing a request? In other words,
> should streams be implemented inside fiber_pool so that we don't need to
> execute a call in a fiber in case all it's going to do is just queue a
> request to be executed by another fiber. This would look cleaner and
> would probably be more efficient.

Umh, yes.

> ** Alternatives **
> 
> Instead of introducing streams, we could return transaction_id in reply
> to a CALL or EXECUTE request that opened a transaction. The user could
> then use this transaction_id with the next CALL to continue working with
> the same transaction. However,

Well, you will have to do exactly the same if you do BEGIN in
stream id 0. Let's first settle the semantics of stream id 0 in
this RFC and then discuss the drawbacks of the alternatives. Right
now it doesn't seem to
> 
>  - This would break compatibility. Currently, if the transaction is open
>    by the time a CALL returns, it will be aborted. If we don't do that
>    we can end up accumulating stale transactions on the server side in
>    case there's a mistake in the client code. We could probably add a
>    flag that would specify if the client intends to leave the
>    transaction open though, but that would mean we'd have to add yet
>    another new key to the iproto protocol.
> 
>  - Generating transaction_id on the server and returning it back to the
>    client would look rather ugly when it comes to implementing net_box
>    client, because we would have to add extra return parameters to
>    net.box 'call' method, which isn't very convenient. Compare with
>    streams where the user gets a stream object that behaves exactly like
>    a connection, but guarantees sequential execution and transaction
>    preservation.
> 
>  - How to deal with open connections that are kept open by the server
>    for too long? Abort them on timeout?
> 
>  - Currently, there's no way to guarantee that certain requests execute
>    sequentially. Streams provide the user with such a way so they can be
>    useful even without transactions. Returning transaction_id can't be
>    used for anything else but interactive transactions.
> 
> ** References **
> 
> [1] https://github.com/tarantool/tarantool/issues/2503
> [2] https://github.com/tarantool/tarantool/issues/2503#issuecomment-415480435

-- 
Konstantin Osipov, Moscow, Russia, +7 903 626 22 32
http://tarantool.io - www.twitter.com/kostja_osipov



More information about the Tarantool-discussions mailing list