Getting started¶
Commands Pipelining¶
Commands pipelining is built-in.
Every command is sent to transport at-once (ofcourse if no TypeErrors/ValueErrors were raised)
When you making a call with yield from
you will be waiting result,
but if you want to make several calls simply collect futures of those calls
and then gather results.
Simple example shows both cases:
# No pipelining;
@asyncio.coroutine
def wait_each_command():
val = yield from redis.get('foo') # wait until `val` is available
cnt = yield from redis.incr('bar') # wait until `cnt` is available
return val, cnt
# Sending multiple commands and then gathering results
@asyncio.coroutine
def pipelined():
fut1 = redis.get('foo') # issue command and return future
fut2 = redis.incr('bar') # issue command and return future
val, cnt = yield from asyncio.gather(fut1, fut2) # block until results are available
return val, cnt
Note
As as convenience aioredis
provides
pipeline()
method allowing to execute bulk of commands at once:
@asyncio.coroutine
def convenience_way():
pipe = redis.pipeline()
fut1 = pipe.get('foo')
fut2 = pipe.incr('bar')
result = yield from pipe.execute()
val, cnt = yield from asyncio.gather(fut1, fut2)
assert result == [val, cnt]
return val, cnt
Multi/Exec transactions¶
aioredis
provides several ways for executing transactions:
- when using raw connection you can issue ‘Multi’/’Exec’ commands manually;
- when using
aioredis.Redis
instance you can either usemulti()
/exec()
methods - or use
multi_exec()
transaction pipeline.
The later one is described in more details.
multi_exec()
method creates and returns new
MultiExec
object which is used for buffering commands and
then executing them inside MULTI/EXEC block.
Here is simple example:
1 2 3 4 5 6 7 8 | @asyncio.coroutine
def transaction():
tr = redis.multi_exec()
future1 = tr.set('foo', '123')
future2 = tr.set('bar', '321')
result = yield from tr.execute()
assert result == (yield from asyncio.gather(future1, future2)
return result
|
As you can notice yield from
is only used at line 6 with tr.execute
and not with tr.set(...)
calls.
Warning
It is very important not to yield from
buffered command
(ie tr.set('foo', '123')
) as it will block forever.
The following code will block forever:
tr = redis.multi_exec()
yield from tr.incr('foo') # that's all. we've stuck!