55
55
REQUEST_TYPE_ERROR ,
56
56
IPROTO_GREETING_SIZE ,
57
57
ITERATOR_EQ ,
58
- ITERATOR_ALL
58
+ ITERATOR_ALL ,
59
+ IPROTO_CHUNK
59
60
)
60
61
from tarantool .error import (
61
62
Error ,
@@ -748,7 +749,7 @@ def _read_response(self):
748
749
# Read the packet
749
750
return self ._recv (length )
750
751
751
- def _send_request_wo_reconnect (self , request ):
752
+ def _send_request_wo_reconnect (self , request , pushed_data = [], on_push = None , on_push_res = [] ):
752
753
"""
753
754
Send request without trying to reconnect.
754
755
Reload schema, if required.
@@ -767,12 +768,30 @@ def _send_request_wo_reconnect(self, request):
767
768
768
769
assert isinstance (request , Request )
769
770
771
+ # Flag for detecting the last message as out-of-band.
772
+ iproto_chunk_detected = False
773
+
770
774
response = None
771
775
while True :
772
776
try :
773
- self ._socket .sendall (bytes (request ))
777
+ if not iproto_chunk_detected :
778
+ # If the last received message is out-of-band,
779
+ # the request will not be sent.
780
+ self ._socket .sendall (bytes (request ))
774
781
response = request .response_class (self , self ._read_response ())
775
- break
782
+ if response ._code == IPROTO_CHUNK :
783
+ # Сase of receiving an out-of-band message.
784
+ pushed_data .append (response ._data .copy ())
785
+ if callable (on_push ):
786
+ # Callback function with data from out-of-band
787
+ # message is being called.
788
+ on_push_res .append (on_push (response ._data .copy ()))
789
+ iproto_chunk_detected = True
790
+ # Receiving the next message.
791
+ continue
792
+ else :
793
+ # Сase of receiving main message.
794
+ break
776
795
except SchemaReloadException as e :
777
796
self .update_schema (e .schema_version )
778
797
continue
@@ -851,7 +870,7 @@ def check(): # Check that connection is alive
851
870
self .wrap_socket_ssl ()
852
871
self .handshake ()
853
872
854
- def _send_request (self , request ):
873
+ def _send_request (self , request , pushed_data = [], on_push = None , on_push_res = [] ):
855
874
"""
856
875
Send a request to the server through the socket.
857
876
@@ -872,7 +891,7 @@ def _send_request(self, request):
872
891
873
892
self ._opt_reconnect ()
874
893
875
- return self ._send_request_wo_reconnect (request )
894
+ return self ._send_request_wo_reconnect (request , pushed_data , on_push , on_push_res )
876
895
877
896
def load_schema (self ):
878
897
"""
@@ -914,7 +933,7 @@ def flush_schema(self):
914
933
self .schema .flush ()
915
934
self .load_schema ()
916
935
917
- def call (self , func_name , * args ):
936
+ def call (self , func_name , * args , ** kwargs ):
918
937
"""
919
938
Execute a CALL request: call a stored Lua function.
920
939
@@ -930,19 +949,30 @@ def call(self, func_name, *args):
930
949
:exc:`~tarantool.error.SchemaError`,
931
950
:exc:`~tarantool.error.NetworkError`,
932
951
:exc:`~tarantool.error.SslError`
952
+
953
+ !!!
954
+ TODO: write docs
955
+ !!!
933
956
"""
934
957
935
958
assert isinstance (func_name , str )
936
959
937
960
# This allows to use a tuple or list as an argument
938
961
if len (args ) == 1 and isinstance (args [0 ], (list , tuple )):
939
962
args = args [0 ]
963
+ # Case for absence of optional arg for accepting out-of-band msg data
964
+ if not 'pushed_data' in kwargs :
965
+ kwargs ['pushed_data' ] = []
966
+ if not 'on_push' in kwargs :
967
+ kwargs ['on_push' ] = None
968
+ if not 'on_push_res' in kwargs :
969
+ kwargs ['on_push_res' ] = []
940
970
941
971
request = RequestCall (self , func_name , args , self .call_16 )
942
- response = self ._send_request (request )
972
+ response = self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
943
973
return response
944
974
945
- def eval (self , expr , * args ):
975
+ def eval (self , expr , * args , ** kwargs ):
946
976
"""
947
977
Execute an EVAL request: evaluate a Lua expression.
948
978
@@ -966,12 +996,19 @@ def eval(self, expr, *args):
966
996
# This allows to use a tuple or list as an argument
967
997
if len (args ) == 1 and isinstance (args [0 ], (list , tuple )):
968
998
args = args [0 ]
999
+ # Case for absence of optional arg for accepting out-of-band msg data
1000
+ if not 'pushed_data' in kwargs :
1001
+ kwargs ['pushed_data' ] = []
1002
+ if not 'on_push' in kwargs :
1003
+ kwargs ['on_push' ] = None
1004
+ if not 'on_push_res' in kwargs :
1005
+ kwargs ['on_push_res' ] = []
969
1006
970
1007
request = RequestEval (self , expr , args )
971
- response = self ._send_request (request )
1008
+ response = self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
972
1009
return response
973
1010
974
- def replace (self , space_name , values ):
1011
+ def replace (self , space_name , values , ** kwargs ):
975
1012
"""
976
1013
Execute a REPLACE request: `replace`_ a tuple in the space.
977
1014
Doesn't throw an error if there is no tuple with the specified
@@ -994,10 +1031,18 @@ def replace(self, space_name, values):
994
1031
.. _replace: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/replace/
995
1032
"""
996
1033
1034
+ # Case for absence of optional arg for accepting out-of-band msg data
1035
+ if not 'pushed_data' in kwargs :
1036
+ kwargs ['pushed_data' ] = []
1037
+ if not 'on_push' in kwargs :
1038
+ kwargs ['on_push' ] = None
1039
+ if not 'on_push_res' in kwargs :
1040
+ kwargs ['on_push_res' ] = []
1041
+
997
1042
if isinstance (space_name , str ):
998
1043
space_name = self .schema .get_space (space_name ).sid
999
1044
request = RequestReplace (self , space_name , values )
1000
- return self ._send_request (request )
1045
+ return self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
1001
1046
1002
1047
def authenticate (self , user , password ):
1003
1048
"""
@@ -1149,7 +1194,7 @@ def subscribe(self, cluster_uuid, server_uuid, vclock=None):
1149
1194
return
1150
1195
self .close () # close connection after SUBSCRIBE
1151
1196
1152
- def insert (self , space_name , values ):
1197
+ def insert (self , space_name , values , ** kwargs ):
1153
1198
"""
1154
1199
Execute an INSERT request: `insert`_ a tuple to the space.
1155
1200
Throws an error if there is already a tuple with the same
@@ -1172,12 +1217,20 @@ def insert(self, space_name, values):
1172
1217
.. _insert: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/insert/
1173
1218
"""
1174
1219
1220
+ # Case for absence of optional arg for accepting out-of-band msg data
1221
+ if not 'pushed_data' in kwargs :
1222
+ kwargs ['pushed_data' ] = []
1223
+ if not 'on_push' in kwargs :
1224
+ kwargs ['on_push' ] = None
1225
+ if not 'on_push_res' in kwargs :
1226
+ kwargs ['on_push_res' ] = []
1227
+
1175
1228
if isinstance (space_name , str ):
1176
1229
space_name = self .schema .get_space (space_name ).sid
1177
1230
request = RequestInsert (self , space_name , values )
1178
- return self ._send_request (request )
1231
+ return self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
1179
1232
1180
- def delete (self , space_name , key , * , index = 0 ):
1233
+ def delete (self , space_name , key , * , index = 0 , ** kwargs ):
1181
1234
"""
1182
1235
Execute a DELETE request: `delete`_ a tuple in the space.
1183
1236
@@ -1202,15 +1255,23 @@ def delete(self, space_name, key, *, index=0):
1202
1255
.. _delete: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/delete/
1203
1256
"""
1204
1257
1258
+ # Case for absence of optional arg for accepting out-of-band msg data
1259
+ if not 'pushed_data' in kwargs :
1260
+ kwargs ['pushed_data' ] = []
1261
+ if not 'on_push' in kwargs :
1262
+ kwargs ['on_push' ] = None
1263
+ if not 'on_push_res' in kwargs :
1264
+ kwargs ['on_push_res' ] = []
1265
+
1205
1266
key = check_key (key )
1206
1267
if isinstance (space_name , str ):
1207
1268
space_name = self .schema .get_space (space_name ).sid
1208
1269
if isinstance (index , str ):
1209
1270
index = self .schema .get_index (space_name , index ).iid
1210
1271
request = RequestDelete (self , space_name , index , key )
1211
- return self ._send_request (request )
1272
+ return self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
1212
1273
1213
- def upsert (self , space_name , tuple_value , op_list , * , index = 0 ):
1274
+ def upsert (self , space_name , tuple_value , op_list , * , index = 0 , ** kwargs ):
1214
1275
"""
1215
1276
Execute an UPSERT request: `upsert`_ a tuple to the space.
1216
1277
@@ -1252,16 +1313,24 @@ def upsert(self, space_name, tuple_value, op_list, *, index=0):
1252
1313
.. _upsert: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/upsert/
1253
1314
"""
1254
1315
1316
+ # Case for absence of optional arg for accepting out-of-band msg data
1317
+ if not 'pushed_data' in kwargs :
1318
+ kwargs ['pushed_data' ] = []
1319
+ if not 'on_push' in kwargs :
1320
+ kwargs ['on_push' ] = None
1321
+ if not 'on_push_res' in kwargs :
1322
+ kwargs ['on_push_res' ] = []
1323
+
1255
1324
if isinstance (space_name , str ):
1256
1325
space_name = self .schema .get_space (space_name ).sid
1257
1326
if isinstance (index , str ):
1258
1327
index = self .schema .get_index (space_name , index ).iid
1259
1328
op_list = self ._ops_process (space_name , op_list )
1260
1329
request = RequestUpsert (self , space_name , index , tuple_value ,
1261
1330
op_list )
1262
- return self ._send_request (request )
1331
+ return self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
1263
1332
1264
- def update (self , space_name , key , op_list , * , index = 0 ):
1333
+ def update (self , space_name , key , op_list , * , index = 0 , ** kwargs ):
1265
1334
"""
1266
1335
Execute an UPDATE request: `update`_ a tuple in the space.
1267
1336
@@ -1331,14 +1400,22 @@ def update(self, space_name, key, op_list, *, index=0):
1331
1400
.. _update: https://www.tarantool.io/en/doc/latest/reference/reference_lua/box_space/update/
1332
1401
"""
1333
1402
1403
+ # Case for absence of optional arg for accepting out-of-band msg data
1404
+ if not 'pushed_data' in kwargs :
1405
+ kwargs ['pushed_data' ] = []
1406
+ if not 'on_push' in kwargs :
1407
+ kwargs ['on_push' ] = None
1408
+ if not 'on_push_res' in kwargs :
1409
+ kwargs ['on_push_res' ] = []
1410
+
1334
1411
key = check_key (key )
1335
1412
if isinstance (space_name , str ):
1336
1413
space_name = self .schema .get_space (space_name ).sid
1337
1414
if isinstance (index , str ):
1338
1415
index = self .schema .get_index (space_name , index ).iid
1339
1416
op_list = self ._ops_process (space_name , op_list )
1340
1417
request = RequestUpdate (self , space_name , index , key , op_list )
1341
- return self ._send_request (request )
1418
+ return self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
1342
1419
1343
1420
def ping (self , notime = False ):
1344
1421
"""
@@ -1368,7 +1445,7 @@ def ping(self, notime=False):
1368
1445
return "Success"
1369
1446
return t1 - t0
1370
1447
1371
- def select (self , space_name , key = None , * , offset = 0 , limit = 0xffffffff , index = 0 , iterator = None ):
1448
+ def select (self , space_name , key = None , * , offset = 0 , limit = 0xffffffff , index = 0 , iterator = None , ** kwargs ):
1372
1449
"""
1373
1450
Execute a SELECT request: `select`_ a tuple from the space.
1374
1451
@@ -1518,13 +1595,21 @@ def select(self, space_name, key=None, *, offset=0, limit=0xffffffff, index=0, i
1518
1595
# tuples)
1519
1596
key = check_key (key , select = True )
1520
1597
1598
+ # Case for absence of optional arg for accepting out-of-band msg data
1599
+ if not 'pushed_data' in kwargs :
1600
+ kwargs ['pushed_data' ] = []
1601
+ if not 'on_push' in kwargs :
1602
+ kwargs ['on_push' ] = None
1603
+ if not 'on_push_res' in kwargs :
1604
+ kwargs ['on_push_res' ] = []
1605
+
1521
1606
if isinstance (space_name , str ):
1522
1607
space_name = self .schema .get_space (space_name ).sid
1523
1608
if isinstance (index , str ):
1524
1609
index = self .schema .get_index (space_name , index ).iid
1525
1610
request = RequestSelect (self , space_name , index , key , offset ,
1526
1611
limit , iterator )
1527
- response = self ._send_request (request )
1612
+ response = self ._send_request (request , kwargs [ 'pushed_data' ], kwargs [ 'on_push' ], kwargs [ 'on_push_res' ] )
1528
1613
return response
1529
1614
1530
1615
def space (self , space_name ):
0 commit comments