Skip to content

Commit fbfb006

Browse files
committed
Distinguish timeout from errors. Honor request timeout.
Still wasn't beign able to fix gh-113 Closes gh-110
1 parent a5b6a36 commit fbfb006

9 files changed

+71
-34
lines changed

src/tarantool.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,16 @@ PHP_INI_BEGIN()
111111
STD_PHP_INI_BOOLEAN("tarantool.connection_alias", "0", PHP_INI_SYSTEM,
112112
OnUpdateBool, connection_alias,
113113
zend_tarantool_globals, tarantool_globals)
114-
STD_PHP_INI_ENTRY("tarantool.timeout", "10.0", PHP_INI_ALL,
114+
STD_PHP_INI_ENTRY("tarantool.timeout", "3600.0", PHP_INI_ALL,
115115
OnUpdateReal, timeout, zend_tarantool_globals,
116116
tarantool_globals)
117-
STD_PHP_INI_ENTRY("tarantool.request_timeout", "10.0", PHP_INI_ALL,
117+
STD_PHP_INI_ENTRY("tarantool.request_timeout", "3600.0", PHP_INI_ALL,
118118
OnUpdateReal, request_timeout, zend_tarantool_globals,
119119
tarantool_globals)
120120
STD_PHP_INI_ENTRY("tarantool.retry_count", "1", PHP_INI_ALL,
121121
OnUpdateLong, retry_count, zend_tarantool_globals,
122122
tarantool_globals)
123-
STD_PHP_INI_ENTRY("tarantool.retry_sleep", "0.1", PHP_INI_ALL,
123+
STD_PHP_INI_ENTRY("tarantool.retry_sleep", "10", PHP_INI_ALL,
124124
OnUpdateReal, retry_sleep, zend_tarantool_globals,
125125
tarantool_globals)
126126
PHP_INI_END()
@@ -223,19 +223,23 @@ static zend_string *pid_pzsgen(const char *host, int port, const char *login,
223223
inline static int
224224
tarantool_stream_read(tarantool_connection *obj, char *buf, size_t size) {
225225
size_t got = tntll_stream_read2(obj->stream, buf, size);
226+
const char *suffix = "";
227+
if (got == 0 && tntll_stream_is_timedout())
228+
suffix = " (request timeout reached)";
229+
char errno_suffix[256] = {0};
226230
if (got != size) {
231+
tarantool_throw_ioexception("Failed to read %ld bytes %s",
232+
size, suffix);
227233
tarantool_stream_close(obj);
228-
tarantool_throw_ioexception("Failed to read %ld bytes", size);
229234
return FAILURE;
230235
}
231236
return SUCCESS;
232237
}
233238

234239
static void
235240
tarantool_stream_close(tarantool_connection *obj) {
236-
if (obj->stream || obj->persistent_id) {
241+
if (obj->stream || obj->persistent_id)
237242
tntll_stream_close(obj->stream, obj->persistent_id);
238-
}
239243
obj->stream = NULL;
240244
if (obj->persistent_id != NULL) {
241245
zend_string_release(obj->persistent_id);
@@ -281,11 +285,9 @@ static int __tarantool_connect(tarantool_object *t_obj) {
281285
obj->suffix_len);
282286

283287
}
284-
if (tntll_stream_open(obj->host, obj->port,
285-
obj->persistent_id,
286-
&obj->stream, &err) == -1) {
288+
if (tntll_stream_open(obj->host, obj->port, obj->persistent_id,
289+
&obj->stream, &err) == -1)
287290
continue;
288-
}
289291
if (tntll_stream_read2(obj->stream, obj->greeting,
290292
GREETING_SIZE) != GREETING_SIZE) {
291293
continue;
@@ -299,6 +301,7 @@ static int __tarantool_connect(tarantool_object *t_obj) {
299301
}
300302
if (count == 0) {
301303
ioexception:
304+
// raise (SIGABRT);
302305
tarantool_throw_ioexception("%s", err);
303306
efree(err);
304307
return FAILURE;
@@ -401,34 +404,48 @@ static int tarantool_step_recv(
401404
zval *body) {
402405
char pack_len[5] = {0, 0, 0, 0, 0};
403406
if (tarantool_stream_read(obj, pack_len, 5) == FAILURE) {
404-
goto error;
407+
header = NULL;
408+
body = NULL;
409+
goto error_con;
405410
}
406411
if (php_mp_check(pack_len, 5)) {
412+
header = NULL;
413+
body = NULL;
407414
tarantool_throw_parsingexception("package length");
408415
goto error_con;
409416
}
410417
size_t body_size = php_mp_unpack_package_size(pack_len);
411418
smart_string_ensure(obj->value, body_size);
412419
if (tarantool_stream_read(obj, SSTR_POS(obj->value),
413420
body_size) == FAILURE) {
414-
goto error;
421+
header = NULL;
422+
body = NULL;
423+
goto error_con;
415424
}
416425
SSTR_LEN(obj->value) += body_size;
417426

418427
char *pos = SSTR_BEG(obj->value);
419428
if (php_mp_check(pos, body_size)) {
429+
header = NULL;
430+
body = NULL;
420431
tarantool_throw_parsingexception("package header");
421432
goto error_con;
422433
}
423434
if (php_mp_unpack(header, &pos) == FAILURE ||
424435
Z_TYPE_P(header) != IS_ARRAY) {
436+
header = NULL;
437+
body = NULL;
425438
goto error_con;
426439
}
427440
if (php_mp_check(pos, body_size)) {
441+
header = NULL;
442+
body = NULL;
428443
tarantool_throw_parsingexception("package body");
429444
goto error_con;
430445
}
431446
if (php_mp_unpack(body, &pos) == FAILURE) {
447+
header = NULL;
448+
body = NULL;
432449
goto error_con;
433450
}
434451

@@ -466,7 +483,7 @@ static int tarantool_step_recv(
466483
"Bad error field type. Expected"
467484
" STRING, got %s",
468485
tutils_op_to_string(z_error_str));
469-
goto error;
486+
goto error_con;
470487
}
471488
} else {
472489
error_str = "empty";
@@ -941,9 +958,9 @@ PHP_RINIT_FUNCTION(tarantool) {
941958
static void php_tarantool_init_globals(zend_tarantool_globals *tarantool_globals) {
942959
tarantool_globals->sync_counter = 0;
943960
tarantool_globals->retry_count = 1;
944-
tarantool_globals->retry_sleep = 0.1;
945-
tarantool_globals->timeout = 1.0;
946-
tarantool_globals->request_timeout = 10.0;
961+
tarantool_globals->retry_sleep = 10;
962+
tarantool_globals->timeout = 3600.0;
963+
tarantool_globals->request_timeout = 3600.0;
947964
}
948965

949966
static void tarantool_destructor_connection(zend_resource *rsrc TSRMLS_DC) {

src/tarantool_network.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <errno.h>
33
#include <stdint.h>
44
#include <stddef.h>
5+
#include <stdbool.h>
56

67
#include <sys/time.h>
78
#include <sys/socket.h>
@@ -23,21 +24,23 @@ void double_to_ts(double tm, struct timespec *ts) {
2324
/* `pid` means persistent_id */
2425
// void tntll_stream_close(php_stream *stream, const char *pid) {
2526
void tntll_stream_close(php_stream *stream, zend_string *pid) {
26-
TSRMLS_FETCH();
2727
int rv = PHP_STREAM_PERSISTENT_SUCCESS;
28-
if (stream == NULL)
28+
if (stream == NULL) {
2929
rv = tntll_stream_fpid2(pid, &stream);
30-
int flags = PHP_STREAM_FREE_CLOSE;
31-
if (pid)
32-
flags = PHP_STREAM_FREE_CLOSE_PERSISTENT;
33-
if (rv == PHP_STREAM_PERSISTENT_SUCCESS && stream) {
34-
php_stream_free(stream, flags);
30+
}
31+
if (rv == PHP_STREAM_PERSISTENT_SUCCESS && stream != NULL) {
32+
if (pid) {
33+
php_stream_free(stream, PHP_STREAM_FREE_CLOSE_PERSISTENT);
34+
} else {
35+
php_stream_close(stream);
36+
}
3537
}
3638
}
3739

3840
int tntll_stream_fpid2(zend_string *pid, php_stream **ostream) {
3941
TSRMLS_FETCH();
4042
return php_stream_from_persistent_id(pid->val, ostream TSRMLS_CC);
43+
return rv;
4144
}
4245

4346
int tntll_stream_fpid(const char *host, int port, zend_string *pid,
@@ -93,7 +96,7 @@ int tntll_stream_open(const char *host, int port, zend_string *pid,
9396
// printf("request_timeout: 'sec(%d), usec(%d)'\n",
9497
// (int )tv.tv_sec, (int )tv.tv_usec);
9598

96-
if (tv.tv_sec != 0 && tv.tv_usec != 0) {
99+
if (tv.tv_sec != 0 || tv.tv_usec != 0) {
97100
php_stream_set_option(stream, PHP_STREAM_OPTION_READ_TIMEOUT,
98101
0, &tv);
99102
}
@@ -111,18 +114,20 @@ int tntll_stream_open(const char *host, int port, zend_string *pid,
111114
return 0;
112115
error:
113116
if (errstr) zend_string_release(errstr);
114-
if (stream) tntll_stream_close(stream, pid);
117+
if (stream) tntll_stream_close(NULL, pid);
115118
return -1;
116119
}
117120

121+
#include <sys/time.h>
122+
118123
/*
119124
* Legacy rtsisyk code, php_stream_read made right
120125
* See https://bugs.launchpad.net/tarantool/+bug/1182474
121126
*/
122127
size_t tntll_stream_read2(php_stream *stream, char *buf, size_t size) {
123128
TSRMLS_FETCH();
124129
size_t total_size = 0;
125-
size_t read_size = 0;
130+
ssize_t read_size = 0;
126131

127132
while (total_size < size) {
128133
read_size = php_stream_read(stream, buf + total_size,
@@ -132,9 +137,17 @@ size_t tntll_stream_read2(php_stream *stream, char *buf, size_t size) {
132137
break;
133138
total_size += read_size;
134139
}
140+
135141
return total_size;
136142
}
137143

144+
bool tntll_stream_is_timedout() {
145+
int err = php_socket_errno();
146+
if (err == EAGAIN || err == EWOULDBLOCK || err == EINPROGRESS)
147+
return 1;
148+
return 0;
149+
}
150+
138151
int tntll_stream_read(php_stream *stream, char *buf, size_t size) {
139152
TSRMLS_FETCH();
140153
return php_stream_read(stream, buf, size);

src/tarantool_network.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ int tntll_stream_read (php_stream *stream, char *buf, size_t size);
3030
size_t tntll_stream_read2(php_stream *stream, char *buf, size_t size);
3131
int tntll_stream_send (php_stream *stream, char *buf, size_t size);
3232

33+
bool tntll_stream_is_timedout();
34+
3335
#endif /* PHP_TNT_NETWORK_H */

src/tarantool_schema.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <inttypes.h>
55
#include <assert.h>
66
#include <stdint.h>
7+
#include <stdbool.h>
78

89
#include "php_tarantool.h"
910
#include "tarantool_schema.h"

test/AssertTest.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,20 @@ protected function tearDown() {
2222

2323
public function test_00_timedout() {
2424
self::$tarantool->eval("
25-
function assertf()
26-
require('fiber').sleep(1)
25+
function assert_f()
26+
os.execute('sleep 1')
2727
return 0
2828
end");
2929
try {
30-
self::$tarantool->call("assertf");
30+
$result = self::$tarantool->call("assert_f");
3131
$this->assertFalse(True);
3232
} catch (TarantoolException $e) {
33+
// print($e->getMessage());
3334
$this->assertContains("Failed to read", $e->getMessage());
3435
}
3536

3637
/* We can reconnect and everything will be ok */
38+
self::$tarantool->close();
3739
self::$tarantool->select("test");
3840
}
3941

test/CreateTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ class CreateTest extends PHPUnit_Framework_TestCase
77
public static function setUpBeforeClass() {
88
self::$port = getenv('PRIMARY_PORT');
99
self::$tm = ini_get("tarantool.timeout");
10+
// error_log("before setting tarantool timeout");
1011
ini_set("tarantool.timeout", "0.1");
12+
// error_log("after setting tarantool timeout");
1113
}
1214

1315
public static function tearDownAfterClass() {

test/RandomTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function test_01_random_big_response() {
2828
}
2929

3030
public function test_02_very_big_response() {
31-
$request = "do return '" . str_repeat('x', 1024 * 1024 * 10) . "' end";
31+
$request = "do return '" . str_repeat('x', 1024 * 1024 * 1) . "' end";
3232
self::$tarantool->evaluate($request);
3333
$this->assertTrue(True);
3434
}
@@ -40,6 +40,6 @@ public function test_03_another_big_response() {
4040
}
4141
}
4242
public function test_04_get_strange_response() {
43-
print_r(self::$tarantool->select("_schema", "12345"));
43+
self::$tarantool->select("_schema", "12345");
4444
}
4545
}

test/shared/phpunit.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
phpunit_tap.xml
1+
phpunit_bas.xml

test/shared/tarantool-3.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ extension = ./tarantool.so
33

44
[tarantool]
55
tarantool.timeout = 10
6-
tarantool.request_timeout = 0.1
6+
tarantool.request_timeout = 10
77
tarantool.con_per_host = 1
88
tarantool.persistent = 1
9-
tarantool.retry_count = 1
9+
tarantool.retry_count = 2
1010

1111
[xdebug]
1212
remote_autostart = 0

0 commit comments

Comments
 (0)