From 0e6b5dd61060f475b73164d9a557e1bde26f2df9 Mon Sep 17 00:00:00 2001 From: zhangchengwei Date: Sat, 27 Oct 2018 11:03:58 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[1]=E7=BB=9F=E4=B8=80GET/PUT=E7=BB=93?= =?UTF-8?q?=E6=9D=9F=E5=90=8E=E7=BB=93=E6=9E=9C=E9=80=9A=E7=9F=A5=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=EF=BC=8CAPI=E7=9B=B4=E6=8E=A5=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E6=97=B6=E4=B8=8D=E5=9B=9E=E8=B0=83=EF=BC=8C?= =?UTF-8?q?=E5=85=B6=E4=BB=96=E6=83=85=E5=86=B5=E5=9B=9E=E8=B0=83(promise)?= =?UTF-8?q?=EF=BC=9B=20[2]hiredis=E7=89=88=E6=9C=AC=E7=A1=AE=E5=AE=9A?= =?UTF-8?q?=E4=B8=BA0.14.0=E7=89=88=EF=BC=9B=20[3]=E4=BF=AE=E5=A4=8Dtango?= =?UTF-8?q?=5Fcache=5Fctx=5Fdestroy=E4=B8=ADTAILQ=E5=86=85=E5=AD=98?= =?UTF-8?q?=E9=87=8A=E6=94=BE=E7=9A=84BUG=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cache/README.txt | 6 +- cache/include/tango_cache_client.h | 3 +- cache/src/cache_evbase_client.cpp | 55 +++++++------ cache/src/tango_cache_client.cpp | 41 ++++++++-- cache/src/tango_cache_client_in.h | 5 +- cache/src/tango_cache_redis.cpp | 10 +-- cache/src/tango_cache_transfer.cpp | 75 +++++++++--------- cache/src/tango_cache_transfer.h | 10 +-- cache/test/lib/libhiredis.a | Bin 460556 -> 460438 bytes cache/test/tango_cache_test.c | 35 ++++++-- ...{hiredis-master.zip => hiredis-0.14.0.zip} | Bin 93217 -> 93219 bytes 11 files changed, 150 insertions(+), 90 deletions(-) rename vendor/{hiredis-master.zip => hiredis-0.14.0.zip} (75%) diff --git a/cache/README.txt b/cache/README.txt index 62589e8..1360813 100644 --- a/cache/README.txt +++ b/cache/README.txt @@ -1,3 +1,3 @@ -1、HEAD操作支持从minio和redis两种渠道获取,默认情况下从minio获取。 -2、若想从redis获取,编译时加宏定义-DHEAD_OBJECT_FROM_REDIS -3、使用的redis客户端是自己修改过的版本(support下提供)。 +1、HEAD操作支持从minio和redis两种渠道获取,根据配置文件决定。 + +2、使用的redis客户端是自己修改过的版本(vendor下提供)。 diff --git a/cache/include/tango_cache_client.h b/cache/include/tango_cache_client.h index 1e45187..df60254 100644 --- a/cache/include/tango_cache_client.h +++ b/cache/include/tango_cache_client.h @@ -21,6 +21,7 @@ enum CACHE_ERR_CODE CACHE_ERR_INTERNAL, CACHE_ERR_REDIS_JSON, CACHE_ERR_REDIS_CONNECT, + CACHE_OUTOF_SESSION, }; enum PUT_MEMORY_COPY_WAY @@ -81,7 +82,7 @@ enum CACHE_HTTP_HDR_TYPE struct tango_cache_meta_get { - const char* url; //缓存:URI;非结构化日志:文件路径名。不要以'/'开头;CACHE_OBJECT_KEY_HASH_SWITCH=0时最大长度256字节,=1时无限制 + const char* url; //缓存:URL;非结构化日志:文件路径名。CACHE_OBJECT_KEY_HASH_SWITCH=0时最大长度256字节,=1时无限制 struct request_freshness get; }; diff --git a/cache/src/cache_evbase_client.cpp b/cache/src/cache_evbase_client.cpp index 4ce8799..5383384 100644 --- a/cache/src/cache_evbase_client.cpp +++ b/cache/src/cache_evbase_client.cpp @@ -153,36 +153,47 @@ static void cache_asyn_ctx_destroy(struct cache_evbase_ctx *ctx_asyn) static void cache_asyn_ioevent_dispatch(struct databuffer *buffer) { struct cache_evbase_ctx *ctx_asyn=buffer->ctx_asyn; + struct future *f; + int ret=0; switch(buffer->cmd_type) { case CACHE_ASYN_FETCH: - tango_cache_fetch_start(ctx_asyn->ctx); + f = ctx_asyn->ctx->future; + if(tango_cache_fetch_start(ctx_asyn->ctx) < 0) + { + promise_failed(future_to_promise(f), FUTURE_ERROR_CANCEL, "CACHE_ASYN_FETCH failed"); + } cache_asyn_ctx_destroy(ctx_asyn); break; case CACHE_ASYN_HEAD: + f = ctx_asyn->ctx->future; if(ctx_asyn->instance_asyn->instance->head_meta_source == HEAD_META_FROM_REDIS) { - tango_cache_head_redis(ctx_asyn->ctx); + ret = tango_cache_head_redis(ctx_asyn->ctx); } else { - tango_cache_fetch_start(ctx_asyn->ctx); - } + ret = tango_cache_fetch_start(ctx_asyn->ctx); + } + if(ret<0) + { + promise_failed(future_to_promise(f), FUTURE_ERROR_CANCEL, "CACHE_ASYN_HEAD failed"); + } cache_asyn_ctx_destroy(ctx_asyn); break; case CACHE_ASYN_DELETE: - cache_delete_minio_object(ctx_asyn->ctx); + cache_delete_minio_object(ctx_asyn->ctx, true); cache_asyn_ctx_destroy(ctx_asyn); break; case CACHE_ASYN_UPLOAD_ONCE_DATA: - tango_cache_upload_once_start_data(ctx_asyn->ctx, PUT_MEM_FREE, buffer->data, buffer->size); + tango_cache_upload_once_start_data(ctx_asyn->ctx, PUT_MEM_FREE, buffer->data, buffer->size, true); cache_asyn_ctx_destroy(ctx_asyn); break; case CACHE_ASYN_UPLOAD_ONCE_EVBUF: - tango_cache_upload_once_start_evbuf(ctx_asyn->ctx, EVBUFFER_MOVE, buffer->evbuf); + tango_cache_upload_once_start_evbuf(ctx_asyn->ctx, EVBUFFER_MOVE, buffer->evbuf, true); evbuffer_free(buffer->evbuf); cache_asyn_ctx_destroy(ctx_asyn); break; @@ -361,8 +372,8 @@ struct cache_evbase_ctx *cache_evbase_update_start(struct cache_evbase_instance //事件通知仅为了增加统计信息 if(iothread_notify_event(instance->notify_sendfd, &buffer, sizeof(void *), 2) != sizeof(void *)) { - tango_cache_set_fail_state(ctx_asyn->ctx, CACHE_ERR_SOCKPAIR); - tango_cache_ctx_destroy(ctx_asyn->ctx); + instance->instance->error_code = CACHE_ERR_SOCKPAIR; + tango_cache_ctx_destroy(ctx_asyn->ctx, false); cache_asyn_ctx_destroy(ctx_asyn); free(buffer); return NULL; @@ -409,8 +420,8 @@ int cache_evbase_upload_once_data(struct cache_evbase_instance *instance, struct { free(buffer->data); free(buffer); - tango_cache_set_fail_state(ctx_asyn->ctx, CACHE_ERR_SOCKPAIR); - tango_cache_ctx_destroy(ctx); + instance->instance->error_code = CACHE_ERR_SOCKPAIR; + tango_cache_ctx_destroy(ctx, false); cache_asyn_ctx_destroy(ctx_asyn); return -2; } @@ -448,8 +459,8 @@ int cache_evbase_upload_once_evbuf(struct cache_evbase_instance *instance, struc { evbuffer_free(buffer->evbuf); free(buffer); - tango_cache_set_fail_state(ctx_asyn->ctx, CACHE_ERR_SOCKPAIR); - tango_cache_ctx_destroy(ctx); + instance->instance->error_code = CACHE_ERR_SOCKPAIR; + tango_cache_ctx_destroy(ctx, false); cache_asyn_ctx_destroy(ctx_asyn); return -2; } @@ -476,9 +487,8 @@ int cache_evbase_fetch_object(struct cache_evbase_instance *instance, struct fut if(iothread_notify_event(instance->notify_sendfd, &buffer, sizeof(void *), 2) != sizeof(void *)) { - tango_cache_set_fail_state(ctx_asyn->ctx, CACHE_ERR_SOCKPAIR); - promise_failed(future_to_promise(f), FUTURE_ERROR_CANCEL, tango_cache_get_errstring(ctx_asyn->ctx)); - tango_cache_ctx_destroy(ctx_asyn->ctx); + instance->instance->error_code = CACHE_ERR_SOCKPAIR; + tango_cache_ctx_destroy(ctx_asyn->ctx, false); cache_asyn_ctx_destroy(ctx_asyn); free(buffer); return -2; @@ -506,9 +516,8 @@ int cache_evbase_head_object(struct cache_evbase_instance *instance, struct futu if(iothread_notify_event(instance->notify_sendfd, &buffer, sizeof(void *), 2) != sizeof(void *)) { - tango_cache_set_fail_state(ctx_asyn->ctx, CACHE_ERR_SOCKPAIR); - promise_failed(future_to_promise(f), FUTURE_ERROR_CANCEL, tango_cache_get_errstring(ctx_asyn->ctx)); - tango_cache_ctx_destroy(ctx_asyn->ctx); + instance->instance->error_code = CACHE_ERR_SOCKPAIR; + tango_cache_ctx_destroy(ctx_asyn->ctx, false); cache_asyn_ctx_destroy(ctx_asyn); free(buffer); return -2; @@ -537,12 +546,8 @@ int cache_evbase_delete_object(struct cache_evbase_instance *instance, struct fu //参考Unix高级编程432页关于多线程写的安全性描述 if(iothread_notify_event(instance->notify_sendfd, &buffer, sizeof(void *), 2) != sizeof(void *)) { - tango_cache_set_fail_state(ctx_asyn->ctx, CACHE_ERR_SOCKPAIR); - if(f != NULL) - { - promise_failed(future_to_promise(f), FUTURE_ERROR_CANCEL, tango_cache_get_errstring(ctx_asyn->ctx)); - } - tango_cache_ctx_destroy(ctx_asyn->ctx); + instance->instance->error_code = CACHE_ERR_SOCKPAIR; + tango_cache_ctx_destroy(ctx_asyn->ctx, false); cache_asyn_ctx_destroy(ctx_asyn); free(buffer); return -2; diff --git a/cache/src/tango_cache_client.cpp b/cache/src/tango_cache_client.cpp index 0efec36..c6fa89d 100644 --- a/cache/src/tango_cache_client.cpp +++ b/cache/src/tango_cache_client.cpp @@ -94,6 +94,7 @@ const char *tango_cache_get_errstring(const struct tango_cache_ctx *ctx) case CACHE_ERR_INTERNAL:return "internal error"; case CACHE_ERR_REDIS_JSON:return "parse redis json error"; case CACHE_ERR_REDIS_CONNECT:return "redis is not connected"; + case CACHE_OUTOF_SESSION:return "two many curl sessions"; default: return ctx->error; } } @@ -194,7 +195,8 @@ void easy_string_savedata(struct easy_string *estr, const char *data, size_t len estr->buff[estr->len]='\0'; } -void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx) +//callback: 是否调用回调函数,主要为解决直接调用API时失败,不再调用回调,而是通过返回值判断 +void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx, bool callback) { struct multipart_etag_list *etag; @@ -220,7 +222,7 @@ void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx) ctx->instance->statistic.memory_used -= evbuffer_get_length(ctx->put.evbuf); evbuffer_free(ctx->put.evbuf); } - TAILQ_FOREACH(etag, &ctx->put.etag_head, node) + while(NULL != (etag = TAILQ_FIRST(&ctx->put.etag_head))) { TAILQ_REMOVE(&ctx->put.etag_head, etag, node); free(etag->etag); @@ -232,7 +234,7 @@ void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx) curl_slist_free_all(ctx->headers); }//no break here case CACHE_REQUEST_DELETE: - if(ctx->future != NULL) + if(callback && ctx->future != NULL) { if(ctx->fail_state) { @@ -263,6 +265,7 @@ int tango_cache_update_frag_data(struct tango_cache_ctx *ctx, const char *data, } if(evbuffer_add(ctx->put.evbuf, data, size)) { + tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); return -1; } ctx->instance->statistic.memory_used += size; @@ -287,6 +290,7 @@ int tango_cache_update_frag_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COP { if(evbuffer_add_buffer(ctx->put.evbuf, evbuf)) { + tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); return -1; } } @@ -294,6 +298,7 @@ int tango_cache_update_frag_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COP { if(evbuffer_add_buffer_reference(ctx->put.evbuf, evbuf)) { + tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); return -1; } } @@ -311,7 +316,7 @@ struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance * char buffer[2064]; time_t expires, now, last_modify; - if((u_int64_t)instance->statistic.memory_used >= instance->cache_limit_size) + if((u_int64_t)instance->statistic.memory_used>=instance->cache_limit_size || instance->statistic.session_num>=instance->max_session_num) { instance->error_code = CACHE_OUTOF_MEMORY; instance->statistic.totaldrop_num += 1; @@ -441,6 +446,13 @@ struct tango_cache_ctx *tango_cache_fetch_prepare(struct tango_cache_instance *i struct tango_cache_ctx *ctx; char sha256[72]; + if(instance->head_meta_source!=HEAD_META_FROM_REDIS && instance->statistic.session_num>=instance->max_session_num) + { + instance->error_code = CACHE_OUTOF_SESSION; + instance->statistic.totaldrop_num += 1; + return NULL; + } + ctx = (struct tango_cache_ctx *)calloc(1, sizeof(struct tango_cache_ctx)); ctx->instance = instance; ctx->future = f; @@ -477,7 +489,7 @@ int tango_cache_fetch_object(struct tango_cache_instance *instance, struct futur { return -1; } - return tango_cache_fetch_start(ctx); + return (tango_cache_fetch_start(ctx)==1)?0:-1; } int tango_cache_head_object(struct tango_cache_instance *instance, struct future* f, struct tango_cache_meta_get *meta) @@ -496,7 +508,7 @@ int tango_cache_head_object(struct tango_cache_instance *instance, struct future } else { - return tango_cache_fetch_start(ctx); + return (tango_cache_fetch_start(ctx)==1)?0:-1; } } @@ -505,6 +517,13 @@ struct tango_cache_ctx *tango_cache_delete_prepare(struct tango_cache_instance * struct tango_cache_ctx *ctx; char sha256[72]; + if(instance->statistic.session_num >= instance->max_session_num) + { + instance->error_code = CACHE_OUTOF_SESSION; + instance->statistic.totaldrop_num += 1; + return NULL; + } + ctx = (struct tango_cache_ctx *)calloc(1, sizeof(struct tango_cache_ctx)); ctx->instance = instance; ctx->future = f; @@ -546,6 +565,13 @@ struct tango_cache_ctx *tango_cache_multi_delete_prepare(struct tango_cache_inst struct tango_cache_ctx *ctx; char md5[48]={0}, content_md5[48]; + if(instance->statistic.session_num >= instance->max_session_num) + { + instance->error_code = CACHE_OUTOF_SESSION; + instance->statistic.totaldrop_num += 1; + return NULL; + } + ctx = (struct tango_cache_ctx *)calloc(1, sizeof(struct tango_cache_ctx)); ctx->instance = instance; ctx->future = f; @@ -755,9 +781,12 @@ static int load_local_configure(struct tango_cache_instance *instance, const cha MESA_load_profile_uint_def(profile_path, section, "MAX_CONNECTION_PER_HOST", &intval, 0); instance->max_cnn_host = intval; + MESA_load_profile_uint_def(profile_path, section, "MAX_CURL_SESSION_NUM", &instance->max_session_num, 200); MESA_load_profile_uint_def(profile_path, section, "MAX_USED_MEMORY_SIZE_MB", &intval, 5120); longval = intval; instance->cache_limit_size = longval * 1024 * 1024; + MESA_load_profile_uint_def(profile_path, section, "MAX_CURL_TRANSFER_TIMEOUT_S", &intval, 15); + instance->transfer_timeout = intval; if(MESA_load_profile_string_nodef(profile_path, section, "CACHE_BUCKET_NAME", instance->bucketname, 256) < 0) { MESA_HANDLE_RUNTIME_LOGV2(instance->runtime_log, RLOG_LV_FATAL, "Load config %s [%s] CACHE_BUCKET_NAME not found.\n", profile_path, section); diff --git a/cache/src/tango_cache_client_in.h b/cache/src/tango_cache_client_in.h index bd82dbc..a9b7688 100644 --- a/cache/src/tango_cache_client_in.h +++ b/cache/src/tango_cache_client_in.h @@ -70,6 +70,8 @@ struct tango_cache_instance time_t relative_ttl; //缓存的相对有效期 u_int64_t cache_limit_size; long max_cnn_host; + long transfer_timeout;//传输总时间限制 + u_int32_t max_session_num; u_int32_t upload_block_size; //minio分段上传块的最小长度 enum CACHE_ERR_CODE error_code; @@ -154,8 +156,9 @@ void caculate_sha256(const char *data, unsigned long len, char *result, u_int32_ void easy_string_savedata(struct easy_string *estr, const char *data, size_t len); void easy_string_destroy(struct easy_string *estr); -void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx); +void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx, bool callback=true); void tango_cache_set_fail_state(struct tango_cache_ctx *ctx, enum CACHE_ERR_CODE error_code); +const char *tango_cache_errcode2str(enum CACHE_ERR_CODE err_code); const char *tango_cache_get_errstring(const struct tango_cache_ctx *ctx); struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance *instance, struct future* f, struct tango_cache_meta_put *meta); diff --git a/cache/src/tango_cache_redis.cpp b/cache/src/tango_cache_redis.cpp index 8557110..e234011 100644 --- a/cache/src/tango_cache_redis.cpp +++ b/cache/src/tango_cache_redis.cpp @@ -11,11 +11,11 @@ #include #include #include +#include #include "tango_cache_transfer.h" #include "tango_cache_tools.h" #include "tango_cache_redis.h" -#include "cJSON.h" #define PARSE_JSON_RET_ERROR -1 #define PARSE_JSON_RET_TIMEOUT 0 @@ -39,7 +39,7 @@ struct http_hdr_name g_http_hdr_name[HDR_CONTENT_NUM]= {"content-md5", "Content-MD5: "} }; -void redis_asyn_disconnect_cb(const struct redisAsyncContext *ac, int status) +static void redis_asyn_disconnect_cb(const struct redisAsyncContext *ac, int status) { struct tango_cache_instance *instance = (struct tango_cache_instance *)redisAsyncGetConnectionData(ac); @@ -54,7 +54,7 @@ void redis_asyn_disconnect_cb(const struct redisAsyncContext *ac, int status) instance->redis_connecting = CACHE_REDIS_DISCONNECTED; } -void redis_asyn_connect_cb(const struct redisAsyncContext *ac, int status) +static void redis_asyn_connect_cb(const struct redisAsyncContext *ac, int status) { struct tango_cache_instance *instance = (struct tango_cache_instance *)redisAsyncGetConnectionData(ac); @@ -85,7 +85,7 @@ int redis_asyn_connect_init(struct tango_cache_instance *instance) return 0; } -int parse_minio_events_json(struct tango_cache_ctx *ctx, const char *jcontent) +static int parse_minio_events_json(struct tango_cache_ctx *ctx, const char *jcontent) { cJSON *root, *pobject = NULL, *ptarget, *plastMod, *pexpires; int ret = PARSE_JSON_RET_ERROR; @@ -160,7 +160,7 @@ out_json: return ret; } -void redis_hget_command_cb(struct redisAsyncContext *ac, void *vreply, void *privdata) +static void redis_hget_command_cb(struct redisAsyncContext *ac, void *vreply, void *privdata) { redisReply *reply = (redisReply *)vreply; struct tango_cache_ctx *ctx = (struct tango_cache_ctx *)privdata; diff --git a/cache/src/tango_cache_transfer.cpp b/cache/src/tango_cache_transfer.cpp index 87d870e..20dd2f6 100644 --- a/cache/src/tango_cache_transfer.cpp +++ b/cache/src/tango_cache_transfer.cpp @@ -127,6 +127,7 @@ static int http_put_bodypart_request_evbuf(struct tango_cache_ctx *ctx, bool ful curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); + curl_easy_setopt(ctx->curl, CURLOPT_TIMEOUT, ctx->instance->transfer_timeout); //测试发现有某链接接收卡住的情况 curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers); curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L); curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L); @@ -200,7 +201,7 @@ int curl_get_minio_uploadID(struct tango_cache_ctx *ctx) return 1; } -int cache_delete_minio_object(struct tango_cache_ctx *ctx) +int cache_delete_minio_object(struct tango_cache_ctx *ctx, bool call_back) { CURLMcode rc; char minio_url[256]; @@ -208,8 +209,9 @@ int cache_delete_minio_object(struct tango_cache_ctx *ctx) ctx->instance->statistic.del_recv_num += 1; if(NULL == (ctx->curl=curl_easy_init())) { - tango_cache_ctx_destroy(ctx); //终结者 - return 0; + tango_cache_set_fail_state(ctx, CACHE_ERR_CURL); + tango_cache_ctx_destroy(ctx, call_back); //终结者 + return -1; } snprintf(minio_url, 256, "http://%s/%s/%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key); @@ -330,9 +332,10 @@ bool cache_kick_upload_minio_multipart(struct tango_cache_ctx *ctx, size_t block return true; } -int http_put_complete_part_evbuf(struct tango_cache_ctx *ctx) +//callback直接失败是否调用回调函数,流式需要,完整一次性不需要 +static int http_put_complete_part_evbuf(struct tango_cache_ctx *ctx, bool callback) { - int ret=0; + int ret=-1; ctx->put.state = PUT_STATE_END; ctx->put.upload_length = evbuffer_get_length(ctx->put.evbuf); @@ -342,33 +345,30 @@ int http_put_complete_part_evbuf(struct tango_cache_ctx *ctx) if(ret <= 0) { tango_cache_set_fail_state(ctx, CACHE_ERR_CURL); - tango_cache_ctx_destroy(ctx); + tango_cache_ctx_destroy(ctx, callback); } } else { - tango_cache_ctx_destroy(ctx); + tango_cache_ctx_destroy(ctx, callback); } - return ret; } -int cache_kick_upload_minio_end(struct tango_cache_ctx *ctx) +void cache_kick_upload_minio_end(struct tango_cache_ctx *ctx) { - int ret = 0; - DBG_CACHE("state: %d, key: %s, curl %s NULL\n", ctx->put.state, ctx->object_key, (ctx->curl==NULL)?"is":"is not"); ctx->put.close_state = true;//仅设置状态,并非真正关闭;内部状态机轮转结束后再关闭 if(ctx->fail_state) { tango_cache_ctx_destroy(ctx); - return 0; + return; } switch(ctx->put.state) { case PUT_STATE_START: - ret = http_put_complete_part_evbuf(ctx); + http_put_complete_part_evbuf(ctx, true); break; case PUT_STATE_PART: @@ -387,20 +387,16 @@ int cache_kick_upload_minio_end(struct tango_cache_ctx *ctx) tango_cache_ctx_destroy(ctx); } } - else + else if(http_put_bodypart_request_evbuf(ctx, false) <= 0) { - ret = http_put_bodypart_request_evbuf(ctx, false); - if(ret <= 0) + tango_cache_set_fail_state(ctx, CACHE_ERR_CURL); + if(cache_cancel_upload_minio(ctx)) { - tango_cache_set_fail_state(ctx, CACHE_ERR_CURL); - if(cache_cancel_upload_minio(ctx)) - { - ctx->put.state = PUT_STATE_CANCEL; - } - else - { - tango_cache_ctx_destroy(ctx); - } + ctx->put.state = PUT_STATE_CANCEL; + } + else + { + tango_cache_ctx_destroy(ctx); } } } @@ -410,8 +406,6 @@ int cache_kick_upload_minio_end(struct tango_cache_ctx *ctx) case PUT_STATE_WAIT_START: //此时未获取到uploadId,所以无法触发上传 default: break; } - - return ret; } void tango_cache_curl_put_done(struct tango_cache_ctx *ctx, CURLcode res, long res_code) @@ -496,7 +490,7 @@ void tango_cache_curl_put_done(struct tango_cache_ctx *ctx, CURLcode res, long r } } -int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEMORY_COPY_WAY way, const char *data, size_t size) +int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEMORY_COPY_WAY way, const char *data, size_t size, bool callback) { CURLMcode rc; char minio_url[256]; @@ -505,11 +499,9 @@ int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEM ctx->instance->error_code = CACHE_OK; if(NULL == (ctx->curl=curl_easy_init())) { - tango_cache_ctx_destroy(ctx); - if(way == PUT_MEM_FREE) - { - free((void *)data); - } + tango_cache_set_fail_state(ctx, CACHE_ERR_CURL); + tango_cache_ctx_destroy(ctx, callback); + if(way == PUT_MEM_FREE) free((void *)data); return -1; } ctx->put.state = PUT_STATE_END; @@ -524,6 +516,7 @@ int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEM curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); + curl_easy_setopt(ctx->curl, CURLOPT_TIMEOUT, ctx->instance->transfer_timeout); //测试发现有某链接接收卡住的情况 curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers); curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L); curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L); @@ -550,7 +543,7 @@ int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEM return 0; } -int tango_cache_upload_once_start_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COPY_WAY way, struct evbuffer *evbuf) +int tango_cache_upload_once_start_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COPY_WAY way, struct evbuffer *evbuf, bool callback) { size_t size; @@ -562,6 +555,8 @@ int tango_cache_upload_once_start_evbuf(struct tango_cache_ctx *ctx, enum EVBUFF { if(evbuffer_add_buffer(ctx->put.evbuf, evbuf)) { + tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); + tango_cache_ctx_destroy(ctx, callback); return -1; } } @@ -569,12 +564,14 @@ int tango_cache_upload_once_start_evbuf(struct tango_cache_ctx *ctx, enum EVBUFF { if(evbuffer_add_buffer_reference(ctx->put.evbuf, evbuf)) { + tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); + tango_cache_ctx_destroy(ctx, callback); return -1; } } ctx->instance->statistic.memory_used += size; - return http_put_complete_part_evbuf(ctx); + return http_put_complete_part_evbuf(ctx, callback); } void tango_cache_curl_del_done(struct tango_cache_ctx *ctx, CURLcode res, long res_code) @@ -616,7 +613,7 @@ void tango_cache_curl_muldel_done(struct tango_cache_ctx *ctx, CURLcode res, lon tango_cache_ctx_destroy(ctx); } -int tango_cache_multi_delete_start(struct tango_cache_ctx *ctx) +int tango_cache_multi_delete_start(struct tango_cache_ctx *ctx, bool callback) { CURLMcode rc; char minio_url[256]; @@ -625,7 +622,8 @@ int tango_cache_multi_delete_start(struct tango_cache_ctx *ctx) ctx->instance->error_code = CACHE_OK; if(NULL == (ctx->curl=curl_easy_init())) { - tango_cache_ctx_destroy(ctx); + tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); + tango_cache_ctx_destroy(ctx, callback); return -1; } @@ -888,6 +886,7 @@ int tango_cache_fetch_start(struct tango_cache_ctx *ctx) curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); + curl_easy_setopt(ctx->curl, CURLOPT_TIMEOUT, ctx->instance->transfer_timeout); //测试发现有某链接接收卡住的情况 curl_easy_setopt(ctx->curl, CURLOPT_HEADERFUNCTION, curl_get_response_header_cb); curl_easy_setopt(ctx->curl, CURLOPT_HEADERDATA, ctx); //ctx->error="Operation too slow. Less than 1024 bytes/sec transferred the last 3 seconds" @@ -896,6 +895,6 @@ int tango_cache_fetch_start(struct tango_cache_ctx *ctx) rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl); assert(rc==CURLM_OK); - return 0; + return 1; } diff --git a/cache/src/tango_cache_transfer.h b/cache/src/tango_cache_transfer.h index 9c85eb5..c5db9d5 100644 --- a/cache/src/tango_cache_transfer.h +++ b/cache/src/tango_cache_transfer.h @@ -14,14 +14,14 @@ void tango_cache_curl_get_done(struct tango_cache_ctx *ctx, CURLcode res, long r void tango_cache_curl_del_done(struct tango_cache_ctx *ctx, CURLcode res, long res_code); void tango_cache_curl_muldel_done(struct tango_cache_ctx *ctx, CURLcode res, long res_code); -int cache_delete_minio_object(struct tango_cache_ctx *ctx); -int tango_cache_multi_delete_start(struct tango_cache_ctx *ctx); +int cache_delete_minio_object(struct tango_cache_ctx *ctx, bool call_back=false); +int tango_cache_multi_delete_start(struct tango_cache_ctx *ctx, bool callback=false); -int cache_kick_upload_minio_end(struct tango_cache_ctx *ctx); +void cache_kick_upload_minio_end(struct tango_cache_ctx *ctx); bool cache_kick_upload_minio_multipart(struct tango_cache_ctx *ctx, size_t block_len); -int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEMORY_COPY_WAY way, const char *data, size_t size); -int tango_cache_upload_once_start_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COPY_WAY way, struct evbuffer *evbuf); +int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEMORY_COPY_WAY way, const char *data, size_t size, bool call_back=false); +int tango_cache_upload_once_start_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COPY_WAY way, struct evbuffer *evbuf, bool call_back=false); int tango_cache_fetch_start(struct tango_cache_ctx *ctx); diff --git a/cache/test/lib/libhiredis.a b/cache/test/lib/libhiredis.a index 26434df401b497a7aaf36de4896ac86faaf8a9df..670ea58f661f76385172a6664ff604f269442b2f 100644 GIT binary patch delta 37385 zcmeIbcYG98_xQhec6PD}kYoud8(J0u2`$M&fIuh-HK7MkL8XKa3KDuxLJ=ZT)(8ir z29Y8~Vw6QeAt(wcNGxCj36C_D2ZM?r3g2^P?hUgSc|Ja$-|x@Qyk46-_q@+J_uMjb zXYS5Uo?lvR<&tX4t7SJ!Xx1#TSyWU)6m90eQBjTE&5+PGIKX1DjI>znZ~y)0OkIoR zfAz`!-x@yLPU+Ox@{d2+|BdqhkGj^fDHi&46+8c%)OLA>#q=qnu9|(ArHUHd(PVAYYIvf2M%P(qF@SUnOQi}q&>{ar+yfV^~vA0V=9|jRA(osY;Msz zdzM+*D@EPk2&%$9${%nvTuD}orW_5dz}_iZ@Y#D-qb^O0dYp;))IKP^&(qIL9X`Q3 zd^`J?nXBb(v4c%x@YYUt)o)7Xpr=PqoaDW*i#?j^yl6FoaTtk(f~tX^=ON=d3s)Yq zddFO6E16Qw21*%=WBK4NW8v%|q?fUH=yjdhA*YO`u-;Hy#;&u+q3{NaXXByt2HWb4 z=FU$s!@F=E1qHvb&TJK2{e^91J;C!UTc$L&L9O4ggp-i*8ym!SLE&$#voqahnAYX4 zgp0M{xXI$(ielhJ628UF@+J93$hyg+J8_rW0WMUl{WQ zaNWgZ9jv~KB|HhY?_vpapx!;~oWwVsO12-n<6Z5iU})#PC3dAJV-7&)7TPfNR8??*UiP|bD$gkF z4X?+ge4;2Wn|DaGqN(g-@90=1o3RY<)q0pJNj4bMK#5})y{j82cnCFuf`&>wW=k4U zL>ImOaU`Dab;K(lGDWp|zfMqUFt)~f+pToAvUef1sWMdwvw7ccs(heg0J$xdsaAFt zZnsu&oWj*MO1$%R-a|bTeVb?{xZ5h>Y$Bw$RhBU?d_~Dp7@dMPM|p34+SJ$PT_{XZ z!Xtm+BlwntRU2GLQ97}{P%jmmYcFJ_VhL|TUMjZM9k08cQd{N6D6B8DhA+(Oq4^Q~{QR`y=al@xhdgiI&<0g9dKV~g!$M(Rkm#pE?@SN2+6M27r$r{brNpI*{ z>uZcHha>B(Q`vLSdcAckTjjmD-a1lcbG+SOwuW2TWbg1T)=zBgpttExD|X;0@3l9q z&)9HW4tU%8J5$bBVf`^J%=`2K>nJDN>;2*j>tl9y!`tYb^>>x6_tyEB^^BG6@cwnl z8m_T(-q35-d8$o6bLN-Y!!>u~q{ODp^6%Q?lq;Wke<-sC+uX6(NNEf1O&Xb=d>}f3 zGK<60^InW5`Q&ZsAI{f>)V@EyM7b1b@Vm9WGl`qEBeRtIW=XK{cWYEQ;naDXqZgsw zb#y=Z-Sow4qtoEs->qLb(?~t<`jxEP_wG?j&eIp~jP3ufqj&(<+Ub@fsx(9VQfW`Ft(|RC^YJi4o z@Yo|my>2GM1aIPB*5?!!3kUC6YXr_fH6s#qngl=Iv&KedqK9_}>z+T}%hXy`ayt-n1yoQjvL*%S1Iidx)OsfZ zF$~>N6f_A^7vcVaAhlWY*O%_yyV?@lIH+a^s=+jkkY){Y;4aF&16r4)Y9Hu`hPpFzVI7A)j-?CpLycCFFRj8E$pJ;-a zD4rP@fs=JC3!ON5h$V3NE0{^*WJDn<_w#P6rUtX<%ukW%(|X_#vf%qeW6)KwAs^=b zwz}F*i3?|}T}3P)bEpNcSM=SXLuj`$>bWQa+)qP|TBr~K-J;a<8OvF-N)}5sGFeU* z(YW(s58ScT)D8MGHVGAUpZ#^8Wc)ZIl^D{PkCe99S`&s(van2;?NV!14N#I%#`Xx) z0EL{BX$5%Or6wl!Rvb9ISslFAH6k+vQ4=Rku&~|=$)lbgK92Sq;C`*~7S_jGtCo7u z%7(y&I_h%vgm+?HbvLW$$Mm97u!#*%e$2d2b+1LuV23WTI5u4{GghtE+@;rr0&kB& z)za%jxelaSn_aM5EQ%+k)@ZC!H2aQXA2uArg_E&rI3A~$V%1Kp9yF?__R|`&S3_}3 z9PF&dLu5U*GG4%(sHZ;35}tu|btRN}JwxBb8nivMm;a zjZ*a3kQw>W`gkGTzt4{;55(Yd{;Bf741Pb~9!Jj8!a9PxAFIsbmv+Xe9S0xB<6%A> zevem6)L9q|1a(kDEBC+#Hg9-7_$5K@&R*D>>Q)tXzH+)I{1LBKhapYWm)K(XtBE>+ zZG-WNY8O`E-JhtYGd2Tk&D6HptLXp`+bleh(8kt!qAivNqcO(SqNVHWU^R6xZSgof zUlQ#cO~>gP@{|!!%i#34sc=^ijqVa7IZ78A$l<+aYLqo^NNp%drW3^{9(PTt=8h zzEQs+C`J9IPt&0{n4?afyH73yWbq$0iWpJd3bd1#iN7284r4sVsO`6s~hoVVR;+%i1paW2GBhT z1IlTuHee@UXIr&q^%LZqJ<^v(5<5XB2iDipOV6Dy%+G2b3V*d#{UcA`#d6pq7R|0U z#Cfho0ABy;O5Z?KidwVgH==qC=&bV%O@sPoc)9`uQK{+`qpUupa)qW%Eb39+O9re; zQL8n|@HuDqE>E>xh0W3Wgef!pcOo3Uu$F_GFv9 z>pG}an6ibzPaScVI@uAYvlpO2CpDQZf{~rn+IVU7eq%_eho`Htd1}F$(&1QL8nGDxbJ$zIK(*JRS4+^#|3OHk_k3biu+y;D;{iW}J(c zb;X;e0dS(L+NN?Q8xTtk-KHA;RVQv!Hb6;dwFV@2Q@gRIu&A3_tz}c6lA4v5WVCB@ zeWFr4y&fz$8P0W6-(~G#U3YAX0r0QxYRiX|*Z>~yp>|+Ju%QP|%0=ZR>XUMjG$|LA zPs+w5T_k2ROS?>*IEs`x{6yA4pR?akXl!AG?e!`9O=)J`Tb>uEKWNhvyZ11x>8VEb zI_w+EVJViwQY?qdV;R(ef_YD=h8GN0&$c;6bG;80df`pcM-bl&EBcYI^N%FwA4$$X zDi77D_(%F>A$79I*KJKXy8fW6m5=pVy}afp%FT^yf|GEvmpa{gMoG?RNue+(L-p@< z#y6rfQbcFUBQmas&XiZTo!+=-$}c;N1NKYrz6^C#C|&}%Myiy|8mUGYxhl#mAE~lU zfy@zVGdT35>VSkCH5dksQd>e!D=mrkTC;uRq>6RcKCYP3QH%CfYzc?P8^*O^&loj? z{?u7HOm%pJ#;CUgd_2rj6JhWIwKhCISq=5#pQltkgjs3__->L~uRN15K*nWi`y)_@2_%x=?YQZBLf@^Ed_-@nywf2A9rJJ~wtJMB_ z>#Hi->qYvwrHCrS&#SPR@sHkRmEnG$U=`Z(NO@CY9Xe@s%DbqtX%E{V8gho=#XWW4 z%9Uz8?~g0g>vr2@y6b|1Yt|4*c^7Y4c3#7EK7CKR#r(gl`G))dTI2s(!*>bhzaJ6H zhpH9quhV_Mr5}T{8QKu1;zh~F0p8cxw4GKcYYJc|JdAR?9g)-ge7NEnE!cR-` zvni=ZcT}i3*E*vMIXJURRdDIu>YQ5vE#5TDPr&(I>Y`4s&04N9i-L5sb?3-q$*o8K zlH0of3y)c2yLje*&<6E?p0#|JXV)3~`}wp?B2Btqp-HyIoLXW(&Tyb77p%;-kMPr zQYUelwbEP?HlJ&)FlnAO3Pq&tOv9EfqRb{mi*uQsJhc$+hz4~2d(~l2eo(F zYmMoj+}gSm;`gW#E&h8CO^s?m?jCh-;L6#PsI9x&4`V$`p<|)iqw4o_j$&pl>xWJ8 z{hU@Ksja)|ZM`0L7pl?t?cisaBsN(dZ#~9#TKCS0vmR$7#-jS!IrgI)p0#`I@iZWc zE$gk5ZlJi++q_F(+1lWBm9a0q4U5!@s`+~%Z*#9Yg8}=Lg~2EL)Fa}%TbTB^*3ujJ zw%Sh1|6xv~chn*EbC#{&OQr?}KdYn$M$EHz2#m50W&wc_C`t{qr&Wl+`6d__GHKIq z^byQctQjoOZXwq2Aq?+&Eoq$nhcZ+u#Cz~C-m)u`Yv$LO+YGqlv0uau49#lG8bc{1 zqrmkMI(mJdp}g0wJ6iM+Il2LxK2qDDN-3(a*5LXWlQED<$#^KBBo<03ISQ^5YFp*X zH!$P`TBLakPN=VGY!+mEuD12h2{N4bfz_X@G5+U+MfMnFQz{$TS#TS(>=3xVP{W-+ zhZs^kW$D{Qyz;JW!NnTLAWSQQw239GJsb~)T*AvaPSKStmd`mp1%+SWcTdZ~aT=3D zkab#($D6PMN^+p&G%kMz!&Sw99oNEnZK~PHBuplEl2^^(Z z++1Ek6^o;#9sIsP-f#yxdO5@m3E6*36>7qK!m9NwLQ&SpU&X`kWRRCKCI z8^8G{yo8QE+{jrY{D=nI1di_!zh%O-Xdv(<9V;E2`RiAQ;mSc4DyQG%V?e~shrQ)5 zlbn{BgcG$YW^f~YTqh`(2SN#z9cseV4A0|-wrWs7xV8x=pjdcqWLPJfu-Q7L|mFtOwvnSm%P{G9Ggl$fCpsshBvE=@}5* zNO=%`gz_L=%X!;`2bwTGS%KDY>msX|zio9zICWVa%rvk2irQ1bb(7p5&~+3a6CKcw zHVT(MRiTjZN`44*BZiy6?V$7rbt|rq=l!V0EC057-~JK5oMG?7=xcZy`5um4Lvb~m z_m69;#*}!~t6W!`FJ)sIWBUyZ;T`b*1&zi)?k`wiM=1OSON!Ls z_%G@fHq@K-tNJ@*+1}ANRea{83<`e7hC21TYIly{=T}ksMm)pPHWA8D$FW4h^?}{O zj(P-~x3JVlVEQerSee`ss?aLD=tzg(OTZ~cKm%!jLgAnXmEJL)q0^1<~d=8k!f z{i!arDIqp*Z^hQhil@ZYHrpU2-UffzY;j7W&0Aly#aY=nZ-0MVb3b;|>j}0E3c|;5 z%4*uCvNJF`$`@(9~Bqx%?SmE*sV`$~GRC%2HjnK`asqT()@3l~B?R zSS?#PCeB)zn+EBWe#}a`Fv_vp|7Ff3LX!2Ke*~5-p}X4V-m*F z>!OqMkXsi+x&-xNFn0<1Q=&m$jBOd)0M1x!k}cqgMd1c0j>Q@sfv;kbU4YT`uvxD< z;CMY-T>1rv(N15)8mS247hd|$lDsONK5(muUoOxl^s7Q@eJljysBepRiivwP*AinW z8w%>%I^zhwidvXB8(=aO(i>o4!SGcB3_2V#8lo^5avP$*X0W;;vOZ9+5w_pskk<&k z_u-RQ2rj;xV;BY{jj-XK=eU=Ip9dC)xGS$gu7vl2I}Qsz1etNR&dSdr@M@eb4$nVd zVK%)vopEsM-OxxywZ+B8TrL+Ct;Y}HJV}2rjE=_!SOA6bSk`hVrQANKmw>r_&_6-X z6&Se^N=^ZDW6keDrrUN9pPX|w)`c03u@7r$@Ooq0KzyRd(Zq&FZv><#+Lk#}@LO5h zuFw>Qn~3!^lqI6^H{fcDEgJzXn&SA0hf>Tr`|@cun?)@jgd zlGc7;%@Id%C&4s-;U)^+0`BIvc;$x(7}6Y@Gz~ncjo%M%Z;mzV3I0i#jDyjXEP-Q` zV1Ku;9dr)kH91C8n#th~U@ftwc0hVdtWYpaZ>f(T|71PaA{kjv$W2D!OmMWq$lCL> z_br;;OpbCO6)_tP{afMC!&D#$Yha}$; zFYuzCl;ibE%{vFWyS1`H*)^Qb-cEB310!K#-ZwH^@o44>S>KvpJ zuE6mq3F9>|;XNF`B;h?!&=Jen10@}8gZ$5PEjwg%!qa=NPPP>MQpSV(&eI${+S0dp ze<((bPcePf3H?NYe`nhnI;1Xi#xdF!9BF9Vk6%z^CHvYAh14`O%7Lsj+t$ch{9w1X z^40pQ27bGP&VnH`-8NOJZ-cMX@o-%aExO}j~#6%Vf#Hi+zo{<=eYH`_8LNrSJu*-q2aYeu*v2gOegr`Bq^H`TpAeXd+lSr3uQA426?4*%|r$Q;=sXWjW2~PvZ z62u?z2!~2|2&9_v!Uu5H5{&Q^6p&VBUdBmD>lBm_9>VdB2QXWTBWnmam*Q*{$hGRy zB^+)HKXgSh1Ts;p9CvvDd(axMN{UIV2X~SyY4w0I!XlC_5)J{^G7~=j0M0;+fsS5= zfr@+ayOI`8R^(&>55XZ_S$zhjgoSl;2`>Q0a+7rz34aEugoX8Z3FAq?Y&}oHpFsiP zXL)GbCHw-EnDNICVCF&V4cz)W3AX_^;WqqA=!S$(LMGwW+&VOxI`@9}wgC^~0AU>) z4dV`IVQ|!A3x-(-G`k~NGWZP2&;XwP1=&D}odnkl2J;Vo0A;)&E;<*zU<(e&owSV4h1K7h0Gae&T+0@8YiJDDYE zy#pnLMfn91o(t?n6F%|)b|c0>(_h3u#p=*)N$Vnb$jL<>LPhC1Y9dj)=x_9Y(LW(nWm@`I9G=zl25h5o0K{2ur7wIp9} zT-`(XN}I#UGnQ+TQXHhN#46n8K7#ef8}AR~^^iqaSl5DD0OgM;_{hEX~K^b8Y+F=RfQv+)dkKxWQN;n8I2n*-8B)kc72@B^H z>ieDwy--Nl%R{Rn;eAj_xB|zi62_&=wI)3L0i3!PhgL9TkydZ+WT&JR3(p`2VC?(v8TgOVcF*r6L9?WqM z3D1XA!t*)KlrUbB5EkDfER^skP(b(-ZvB#k@zRm-K8_Db_!D3oP1c`D_!PJapW@cH zC0qqE30L9wqZMiW95->ri8tPa)A-GBO$p<#776#}xT%DfKpEk)yzG7wt^%$CQ`t{R zI1Mrgi?ZiPxHsey7G=LE;U!Q=SlnoPC42-*3H$NLk4v~JI5wG_pOx@HNF{uiTmLNK zDv(7uhktEhjq`2P7odRfFur^oCgEqGgzziex`l*8fW3@(61VOt;UnNioLRu5l zQPXP@J_5Oj%WJBC{bCxrqNWw%eOq7DG(?iSp_EE<^MtB~Jj*RW5)>qxWog-S`A<0GS zJ0-arGSQv?O@6eufz(%VUhbhMsgFv^qIE_~a#8UtNxm1#(0O^+J}=>M;KIV3r+L|4 z34aY4h||T1=(vQhaq~Oci|rpG?<&cEHvHGOOp$=-xH*!%H)QNG z^^8ZtA&^U0^vq@n{xCx7E>n;)wflR`p*#}Gb z2zUsKtK%sWUIN90MdWKGycEg^i^yM>a0PG`Ar_Gzm2gkUAS@z3Ct*Cf5EhaDDq%di z5EhXKH1}=PB~Xeu{dL}`2@<}*<;jv<#M)kxSBKO$u(ayoMk$X<*acaHMOB`X@Yhg4 zSj;JNBs>U82#ZO>BjIJh-b5@8fh`iYgPX9OUjn`*VFzR)hQV*z?2eNX>jWM$?Ziz> zCENpw$@CDJ-jvupC?nH(+|)nGxA~t3*IvXG!VGbogcBiyu(;z(mGC6UCG6zZ!zA1g z3JLcNH=Hk&a1N9bKEm(p)=2mZaClAD2PKT(XA>6IUr6{1$RhkGFZ+&!XF!43I=N-cfca5t|&s3aE^h?3;Of2=M~zQ2|u z3TQ7GB=NrOD#?37>08+R$&p4p<0L!`9B(6D&W{L>gttH{;Vm3*maqz0gjN2GfLFr) zP(aw9nmPIYz=;z;ytzXtmiA#=9KCqTb6T916LFMZI5^a5xka z7WIBh!d;=1a1yWBw+~>)JBYh-d{4qtAeFFawaTrG3W`RZ30Z_itHnro78DQ`t=3w? zd!dBzLSFV@3BL^NUBu!6m5CDG3vR-Pxb;d2pM^}qXF1+3;Yjchj^xjT9FTA|C?;Hu z<4+|#2FeJJ;rOD2p9a@K#7}d4N5Wx{LHMg`Mq}1!?c1nlA(ya-+%4fyC?q_GJMSRj z9Z*Vm6~`kVz>Y(RFLV5ygsqTD*q=Y{vQENbkVQC(<3kc|2?c~(a{QTu2SN$qfgE3w z@Hk+_h{tjKr-Y}1o3JRmW*gsDi-%0Y@!Yzxgr5Qr;iow6DB*EXY%co=2~UMGbJ=qw zjK9e^jLu`ZbB~0_LI&Zn9B-B|E^iSQ^?qBzQ=yQssP|b3w}Dc^ZMgHFB|H@z@0qN_ z+WNK{F7_by7uNN_gISpN9zFonmV4|enLGvsM8cDygj}S&hnHImBsK)t`)E3Z zdtN2s;owG`p2P8e3IECEA3Q{UQj*)iV|MqegoV3%50U$&_%@Xd%FON>Nm#f`dWbwl zlG`BTh^ew8BrM!zJw!fTlG~sV-8qA6TJ&v$gd0LB;f5T)E@6B?@B_rXI6flb!H`OL zFvs6WcqC*I7G>X+a1H#S6XF`&+L3C}H!+6{fD*z3IF6R^U|=7b%5Ev)k>DmQ${rx$ z2>d-2;t1}1yo3jVhwvbd=Sg@l6r0OlE#Z++W-j}HgkAVcEp+bU&OecG0%Q@W=J?4vIvXeutdVc z@por<2H0~H&j5QQ))z|1v@iGko`mri4af0xG@j#2P)weZj^m?Jr;ee!+mild$V7do z(68Cvw~;1+hwvosuCatCL$TSqpM)ntnc4a&2~Wmf#hJ?XNO%%t5Ef-`mhfcAHCrE- z@FXZSTc4HiWN+z5wvhpm;^D?^s&B<_20{Ahrz8v_zBK7CdO$z*OItYoG{dn?LSrBcQTYRJ z`y~7Z6cE-NMj&5GxB`?A7Ed}|kuZLH^A+Ob-1?S;PlKEA296^%-?qg?RkL-hginKq z@DXmECgI~yOjtbI)K9`ypp5X;%0`*fBs>dTU*nfp6+)oK7W@*c8DwDAnH*whuadMo zLoVT9j`vBp85EkWk4m^RloD>nt*=Np864jr7SFHTlJEjZB^<%m$0GcE8?hr~5f)#} z#!47h(Fuz+yCezYDmvowb?r0>ixsY3l3aWt&`**t0r$72Sf@$2BV-cp=QOIYNW#m( zqgzK9c$puBp(Ka=nj7J;B&6A5}N>}6iF~&B}tPozP;)kVzGACPr|tRMOdtUjgl~~ewnQo zNq8m{n5|by7+1dti`B1v5?%uAJH%r3>!^g2!Hu|l{pyN@#q!V3l3XnR+>+#C^~ZP- z=Ka+UvHGLGFcZ6j;YYzwsCxhwvB4 zSaorKe#;7RE3oR*E@Rcj)q5JhfD$(2@ps6!s`p4D8q0{rx0kIKigk3w4MNe# zZXC$%qNi9`!3LhecOI_7UHxo;Z`G$sqbk0_HvU-+Zfjb!QnwIl`e~urWAW4#^A4Xg zVm=T%C449LTfQU8w7iQ`UVTx>Cz$Dm9vZMmlv&2x1$1-~lA6{=Cg7)7PBI zQ0#Xau-@e&*lgF@wJ49Y7MgeR*Ih6-npy)A6ia!fS|jBTYvTJus3fTAuQjP!u0XYJ zN?xk(t7OJM%^*@050qFq6`<9?H*Z`wlE4aDq&3zO z01l^CH8e`uiaIeJ`SED@gC{CzwX$Q1uqkLOkFgNDMQ>ng2G$hYx4h!0Rvz}_Se5b& z)uBA&Q{(@kZT(n=H6ToB;I&rNb}7|krdQO1;Z>f;b8*XXhhBZH)omG*&TnyyTJ+($ z*gXR6!~dawVe-<8ZaIRqqhSs|yVVWsYe^_#e*UI04&ln&(Gq?ymHwK{$4BLTjujor`@=Jah#?8w+9< zyeo;P6PtEJ7j>gc1vQ>dY;0ipX-yb(r^^P1G-S#vL5E```V)s^wyC@Lv6rqFf`9HG zj0gBUBM2*DHSk;+Q^MsjNBNF^j3j)EIjd*SoP^8z&Y?Lye&j=-+`*7>cz+(F`56P; z663(QXp6bSHI1XK8W)$x-x;qt>A75tP4(bdq$xPbX9~uKwr5-HNzwMCy7%YYQE2Dm zBnit$C;cDp#fDz)Mc$wHspx-Lti{r^5aJ>z&e_)O|W6~%A&t=i~n)tS_3ZPdjKjpwU`*`@~B6E2&~-Od}<+Y zf2TIxn%}lVc&5u{vD#Z!NUo3`qF|rZ!ffFEY;98(J0m*LN4XAWP0DrgZ2%z-R@pBl zVr4rg!*g2zp~}4B&fkL%iEu+GeZq;@0!C@m;q1TXq*l zX`jIPHTZ&{!6WdMu;a7TuCQkgzRK6QWAoz`lXeQ=*m{ku-=IwtkX^)_fG+~92oVFdiui)Ok^x$S;3s)s zMp2p;80?K2s7+G*SMj^FYLIn+#c%z1u*UGcKPNJ^Y~{=6pvMsHU3`;8rJ-79Wjp@w zI((Pjq@h{_s|ibnYHjfiPA4d-36+Lnk^L7?&%#R3bcFU8zJ6rM2rZx0 z##bY2-&CGJ>pHmMwFTa)G7H`~-W;j5!AXaGqK30J(0!Cfuh*GP$#~c`O1lmpkJjw@ zlk$R{OLbG5es`qr@;~`-Vzh=&5O6%w%y54l{Ds(m6UQB(`xq@8631x4&YfJ=MKURb z0jT4**T7Klv^5l#kI|~I{ZKmG8Unp0SZ(@V{waJJ0cS z8vg@}XPg$U=ik75AgwGM;2{rH^LwlagFnY<74ug?MP-tje|LEpG<-&@2;1gbD^{w; z*XtEDr~nzyXyLm34sO3g)9s%p{V!2pIiTqd4xm6+6sM0acDRdg3xuDZ(W3QGs*OjJ zTNAX3m42#dIHMx$kT+h7uS6j(;zbOFN?F+A-;UQ>L0T3XMQ7oAv5(HPR)oH|N6r-g z%K7J(g~3|Hdj81}J^wN0^(fYIU*Cop)g?E#(1UU<#HcUEp&K5qq8mPmdAr z`~R@F%S$Q*cPpa(po#viutg z{hem`WY<)V$8fCQo1i+KcJVoL!g%#nzKO|=a42L7>ka$}7MBSI_6R(d_gy#c$H2t` zXL9_w4=xjUBzHd62fL>6$ZvA%1wJ@K;6mz6+}0QguXnD%jd{I4@WF)wU*zJ?eQ+t_ zbZXSWe68Yw8RLEvUg%XxK9%d2ndOi=omXWpuPNg}8SRuM@MGM%k`FErxHE5vNFQ8+ zIGbWU!pjsj)}5oQgvZ*(Y=-hiJeV$$yfxQPbL+-tjPZ!(X)DPWa(CU#a&XMzv992Fgbz+dte5sO z$2n$x?moj zkQZ?|{m%y4gxn9uO7q!#tbAcGOET6h(nGGjCmzNbj?xjg2%lHA4ROC|Zw zJa2xzBOOP{Rtx+tV*HaUy>2!J*Bo&`bKgDqU@)3FL*T2t*}w(QjF_vGScjW|0-k$5vG0UL< z-RUQSP#(o=KDb2SWxQ^m`(T#Ct%Y;(CBD(FZh=4GWs8>p8aNZNKDveT9()9emKn|4 zd%7fF$b-n0o-tx~G^7i_XO$Oq$woEb@&ka_a{>uQ8SX?UwPj+BzX#tBT|xYQc2+zuM@5dE8GY75>TmXGbQ9vh&} zcP2x#!ymZZI5zy}Yw=EMAG~|kw`hMO)!Pj+=4*o(J^+nc%mJnIwa&(D&MQ-5QVxaG z1^g(r@j=p)oZw~@m4z66{)b667e6)_nQnt z!HpR2Fw&pZ;vsD+Ud{ht!Vd5tHss>#P{IxbVRf$)zL&3K#N%U**+Y zMeT?ic?f}0#OUERDm(Em-;#qL+TJ&5IUscr`oi~7F4CsLqPbc{rD;XIf1qNXR?$hS zhsX%G(flriykoWUcw>r_&?X<8DeyVo6`%TG4`Tgn6UXrtGsXh!{BZbHlK)1L;MN5f z4QVriDHEmb;G^UPAMARL$13m%ADn?$59Sko>@?&H=DKq%q!JINg(Tm@OPgYrL!l@w zjJsRogG-;&yV9|k$0TOU(;e{S5CYZ>FjEpSUN&M;y8ot?m6^5^Wbe6Z(vJZd@XxO|*#N#Jx<{%3OvgA?mVqTq~Y3 zxEWf-=mdRzWhnbE*DH~+oO>2eb*=KT$z5(#+)%!aIlX{O{GK?7H@Q(jsz)!Nzel&p z^XLVXP|gq73))oUT)>;*x{s;n1>Q5`V2@_$u>JW~=lP-K)6ED1O$8;>VLwt4zWa_RYG6lSGbl{ckd_RL) zCWjfb$e*kDEV7Y<7fo*Q@xs+uIKF{xwYF8SkGQINoSzkq!W}R1!aKzpUPhTPzN`Hu zy#`rAYZ=#i*`$TXxWM0VTxi1hf)&KrW>?9VA2`?GDDi{LHG0lN2~Nptco^O58)0nZ zN4ODXnW5!ciN= ziX^}Itd_pjGm;17Zb^>sY1cP#Sx#B;Np2&sozc>iq@p2G7*50USe{=HEP%NW4r%_Kga=Q}(^ zF1m#O1Sb2gFw7FQDzuvHhz(&Z$e%F!Vx7)9wJ{M$u}G3mQ4?lzbeV! z=K60M^6c_)DS%i>Bu?>v$_I_lRFaF1J}b#ZM_=@j_ql(d{OkkpD?*;XCCO8G z-b&HoMp@bw@(M6^GoIAK^rTA-NlSEVJxMOQ)h)?I_jOZfb)j-!3CCJs_gyW_U({|C zWc9Iyx0@uXiMq^^b`g>TkIFTKN!ru6-{AZGy z!kg7k|Y;3`L|w^$Uh`3YNA+;vreFqI>PvMg6NG2F!mL!K(#GayVAm%Ut?Do zY<@)xj+{ZibISxtE{5;yhsYO5^6#+Y zm|s}$@3_BJ5*O#GEf10JmgM4ac*kguE=MH(4DW_h50QT<$;Ej575(A)B3mrCiuTIq z{`^#<0yylb{=zg5L+R?iW zg+_AQNK!x4S)P%U7>V;J3B8#|wWY1u!wq)P;d7uA(KA&W^zg1mTUER~u zJF~m9VoBVSPsJ6-c{8)xWVOnQk57+RoBMx!d}c%U_yH0{6o z^ZvIL1J~2L=V<@&pZEWw{Qsk_adEDu{`%63|7P#`;RTKTZU0Wpv4W;dojmTrF_{lY zF~LeGofnj6+1=c#H0M~v_8)_;PAske$idQY9&T$*7&c|A1UouLMtnV&Tw?~#$5#o;R^`8CO)PFKweg1V_)GzhDkS4m9 z{_w&KF{HF$vwFRB^IrXHqcs1;=VR8GFm7OL5ajIDFsccEAP(I!M06^hxFt=5m9F11 zL$uuib9EFH&Ceq}mm&B&%Saf~_ossiMS$bLY5ckLvm&GR0T^9W+mg>Kovi844s#qes{96== zjdH`kMUUuEbl(t7k%__5xFXUren-m-nD|5Nic-c4*t0FCW7%K0lhF8<~iX!=GHN8NblFfr*7bZ)C^&VoJ??kZf3lbm5(%Ska zaZqO00o66WYjyPb9@rPf>M*Qd@`cyaC+gx+Ur~bok*=RHeRn45mMIqd1}E!YA#!~u z8pB?{3CCg+JymS-j@})5F1C~2BYGN+*j26k&2E*Cc7mR`k@H7%*L@?p8`DFp zJ~(Q|)QRIqJvc>1-(xIxPZrzmF)nr%kI40_j7YIt4n8lM$U)Ps>b_rA8Bsz=UzIh+ z%R&s4zO}{-(O;&mGd77~zGLf*F{bF@>$t&)G(-pAJ<9Um>CJm75t{N|i0kY5UMyiPS&H5c?r+8&b3z<6@hEv|+ zWsa|TpG-A!7wUNnRXk5$Gq%(iVB6f^C#35haMSa;u_s=&04lDAF|R7xZF5!3@-_U^ zSfq<|`N~bBZp}wQ&4~nz=E##bjpUedVByW7w&jDiEO*|%+=cr?=H@Q1XBI49Xhw+m z<;%@vGxuO&?()~o?jnErpJsb#LAEdxqjT(5s@7%fJ9l>U=+UVm_2#Ogd`OsaqOHG? zs>+B8SzCU?Y$or~&Dw5r(eZ=#k1p zZPs#&_9m<5?Ys%wv~VcKtKzh(xeI+!@*|HKkrD-9Kjuh-(3}dp?Fw~s7thx~o^b;7 zlVylyHVm~5IQEp4c-hS|Q(@wt3PR}D)s|Ub?2~&f^Iyq0%tPkB4K{MKcRM4!O76lU zB?+0=9h~GIEXtDaRx!uH?2{Q}-UTKW1eu-d;y}6tlSc01QujE5>RIwkka=%xh5avY zfFVEovY@K@aLfR3Q`D|_QpmD>bN4OiniQJ1xLZ)~kgmJ)eHW{mF(M>i1y=NMyf!T^ zcX81G853+aPtH+r-p!D?C$HINog+BNSnt5NnWpR))kx7?lyDut_4EgtZv4NQim^;GisQbB3Zsz!z_YbYE83U%i3pd-VCXi z11;W-ZJYXyf4jif)N1zFaR!je-ujvlhHWTbdP2+v@cO9`vsL!4?{D5b+ZJ*hQm?DZ z;{V0w%@DJPcv$ubH7|-MWSd%MiWt0UWGzz!jero8Z#n6PC(3iLI)ddt3aoCW<@0O% zz6mpjRBe0rD&wN+MX4r~S|p?ECZ+Z+nXSSW~s^M1OhGiBOvt>);zK_SOCGtLYZ zNy9&Zg1soHIYKGn>yeG1cBsQg`Chus?5wB46yLczI2blU6H(5~5yREXFwjd-5y0zQ z&`1P@XjwPjJk_s6w5p+LajHs*s+5Ez+oq~KSSS_y{5=<> zYD-R>JZh>YhRePQW@2oxo()WtQ`KNy8CO-S%O?}e7A^YgwO}}l2C%YrB6C1IybaJq ze_iqT2Sz=pUN?c)iIX&Or|;JUbFU#r$Q=#LVsWppTSN0D(Ktxhu5uv7j-?>sey!S` zsM1hX#wEj8Oq6|+&A8Tyc3V{7T_C9Xc6(H*t5Qu8-vq&0r6ebD95ktc_*%t2a+D?- z%CclLQZ$x3lVP$=kvEgg0cJDtVja1!yIEUKY;2~%ifesi^Inl5uQxXHMW*bNVkU^@ za$<@(wrUFz9jR$8E>)NRN;G5TwG^1aTgtE|W)qf zMIerxmmjDI%#l}?yTCx2K((XL{Db-|T+ca!c%odF21of!`Cgj&vH2JTBmdRKtRuIl zo3+eMdfnS(aSQ0~FVoFdqI6SuhN+wL^rQ9U;WX%^7R}97;z{{Yb91t>SzjiXwt$+T zT2qc`VKxxY`IfXW^MrU*9&2fK9J@*#7qrcV`9y7EO-YibH5mu7uA+>m*n(B6qt%uM zqjojrJ4qeBYm}va)e;@K`kzDQo=ZxS7qZ}do+F25n~BDv;q~RAHfEyi-Np=;KesZ+ z8H=kVDbz+j-P&9vUXZtCnfH3Px`P`+*4F&g5QE$5AKX?7&WUv!NmZ;b`NjHj;8 zsyJWwi_;f4PT#rYTgRD}ToGru+?B0z`G$+_S?&#j|i|)<9(H%%@;_h*=NdBX}S!OH_YvT0s+79L-?z&SAAn~C({>7bIzFj&d{|*`hj@^LZ#9f*dWHyD9TAON`c9$*x zlJcrbnd%>GVoeXwYNAHym(H{cGxnY(|*%zckzOw&fHldV%_8je{w7EmhIywD7$GZoG>KSR^ySKuDrJl)8F z!*htt?PTV9XF2DV+*CXR&a$f{C|hEdeJZ8b&S^#ykJ<6S5C)CeVnZ;Ve7yEK*q-2{ zY=duNSC~EEovD1Y8=SYwy1@yqRQ}n`%oYn}o9?j8y(I7JZWf5o_w zv0D$bC#(sIdze$qw?s}0d7~lJe>L33@KdPKEYZE((hs3!zbTkh#;ZiKV* zuwL*EX^33k%j^(3T-=welH4H<{+m@8Z!LA}kmwypg9w65^uWHie@ zPw6H3e|6hVmiIQ_6kX-SK9GfGImbR zJLoJ1qZv*VJM`Ij_;t0<)vxJlI6-J#>{IpY?2PKGDAPeJL;FIn?w1q#n(_Jj{bSkB zV%g7P*El>7^L2_7%d}!!lf8&Rl@x#pc;fhe5h99<9 zhpKO>+_1eWsda~1rF>wY%_~~|VMTRkE%1>n%Qqh}j_cX-H2ZK^x66G@>F{($@gHP`P%mM{ET&52;d&->E<}jI`Zr!({yH#IaSYURRWsjH*<-V2pZ^a@roc=1QRB_7q z6_AwTNuX&L_qDSM<&hDvXenN7M#&2gfC{{-8s5Ks)@C*TzIcp|9^a0@;I!q>?YXJ7e8($$ozIz z7W661HPC6wb%htFiRJNDEtQ3Er>NXl^kn%v_rk4(FO?lb5~=y@52|(8oKyee!11`ea9Vh4oxfUXbK}`j;R~> z&Kc6XZExd|)DF4rv)iXH%ewsy5XJNa(deG`D`QO0fhF5sEZJ@9UjV4BYVGpQDT3Dr zHC5;>XKpiN>c-D8X7*Id$F`aJ6;)LUcQ~3K%2&6U3%b8FtJoBp4#K|~TgSYY-G1EV z$J-Bl`W_>>XUW`mI)MK9S;gB*wjB!^)T0EnmK#A+jqhg#?Haf&Xv~zp-@n%$R2s^{ zm&`^%-x)#iP`WB#e#vYpUX-U_G85raiYPZD+i!bm+ct>8=(KgHF=^_wqN4djdx5#u zDx#dJ$c!3u6wI1q1Wzq8!jBp=w-)`8V7w`}zHCOd`7cbwZk>@}ylz)-_g_@6zjgZk z1GC#3TUL~tQEmSV11+5<$bRMK>ou1@HdQ6MSI}F~#&2YuSIpaEzn%Rq6xNCXkcMw( zw;Q7p-P=y|dO7MRA((p4e)R-+ddUyR3K_x+Hs^j0% z))`YT0q(X7`}6rt*IqG&_^0pst7di6m*+Dd5tehCOJ4j~M9Jej&9_}wuVvmKtF7;= zznh&cU*bOVC*if1!<}k|KB0H28C7I-tr>5O7u9M;0qRsUs9SIpO!=X3(M4_cyAu!; z!2lLDgES>;8bAgMcP$rX|AP-xIq{Xe1uJ-cc|94oN3;@?Wb=2-j{5O>FmXo67x#!{ zdi^83u6EqMXrgJ~YNes`B4meQR)T=}b%fPW4mt>v{{lJXAWTnhMjAnK*Fku*pDQl| zfW=Sqcfo9YqTDyuh>&~MnW1vkyHFunZU;fN{6y78P5U7S?ADbr?}4aHHh&L9tw%Vb zBOY6{3PjbajC0tvE;joDm>zYX{PjJvLp6PyBg$(_JQz+J%ijhw z@5~?S3;WOvwW`@&2nt@kw0u#7?EIM-U$r>IsWC*3|IBPu^+G5WSF2)vm{Xi94?)p; zD%>f;dv1HX2i7iOn$SY+^*4Na0QnT;@yO{dPBHSK$l)@Ky_F*`MBV`TUgYHt57Tl` z@EHm&$fD0-FjRrO;v zWqy$np?_6V?wbSqm=LF&5Mq}zXJLY%w$=gu;CijSJ?-LoF1{Y>7lNI;LmfN!g*tYh z!EzavFNMm`$3gEVaHaoxEl2+iIH{>Pe#f#F=9KS&C5qCY6z1qR3U~BV!yWnkSboSU z#~jAK;&Iboll~@b}sI=*Tu!tUH1B*y*piUx4pqG?zT7F#WP&?#yj@fOm@lL_8xI@ zx4lB*@@uaVD|bC%RPR|r4D7pYtaNd=jrA_x+!fPiY~y~EtF9X8lHYJ~^)89}pcCF6 zSNelpd|#a1r^DYyx$0B*(EGzx&+VtjZJ-F7vUeZ+k)LN>-0dg6t~10N;6%gy3`VZ( z6}aqqv0gNu1C@M;OWw!Dhr9Sg_0*7+&;4Ky)f>jieQ@~tV$PUZy522D7A}H=IVVQO zPqiZSY#7z5{5l-GP_8S!(L{hLum{`jLgNsN+%&zWg@Ps{h@Ik-&# zR}8a%hRJk`T>UfP6Q=L*&!#2xUku-8zrbZ&u}TJCfcdkB%)Vf5iYbH3FKXMZS`S+_ z_)CPp8>YN|!R#JA2Ia{xW2=qi5pwWFb4F%_YCLRDF>xQPwuIRkDp^uKJT#h6&BAMVN5zdUlyW%GHF;_LFO33uf?__D8J7y67U`#` z7qE?Hyd4HJh4C`s=od2n3))%Dc${VH%ZtC614W$db=BM?cKR+~HQ{3@NwUiya2KtM zT>J+lxr^NW2MBA)5!cM6aALcB4NAqn)z{7W9{m&3m!x~T8*syByvI|Z|6jR^G=goqPze?89(@r}%m_oT&~sOdyKroOXRjZmE^Lgd_d z&r_nV3{UVBhz4>>f+r118(WLvVVQgQZYz=TOUFhCI=^h)j_!G_-6xutA%ny5-6{g%^N@@8)az&Pud-8 zQF*3)^#J0>u+fxg{Bt|CHH{p-Rr#JzS<9>2{Q&4_TUTX@epC$)4^Q3tnMCEX}uB|pwo{G`8V0;tm z=Lg_p86S*x9%uZBV@Fm^^)yx=%}Vw3&_ip>S*e~>c-OE6ig{P?*u0~ue`vJSoP(S) zbODe3g-pLtW~V{s{w9mkAZ6upyDA-**Hr1aY?5x5rli}Y4Qh8mewq#$dPg?T@az?L z%gY%yte*+Jf7T=CW_pH*EZ?`89{9jkmW*xTSsFdGjuYbG7gL5mY%)C4&XxQpGz;lM7mJjYI&`l`g z??|JyCrz&wEnBqqq(+ZLvy+)xKlx~DNY_MpLhYWC*;%mLCReN76nQPnvp0G!rsus( zf6s^Hr)?nphh%J9NO8LC)fNV5x;){Og0n$3QTEUFEX`Yu89de8-@*u7B(e@C+0J*M=)6~jU2G`mh6=SBW=D6?&K-(uEE7jo!0&) z$0KjX_(5Dubz}Sj@*#|OLpu*KKFQ(oY$wk`c(XsHGxSB7G`c`Y2e3-hEdP++L*A8f z9r?YCry!q^_ zG3r0acrUr7J6O+=C%Su%saa@84^L`F0c!Wj_P72p@`o5NlHs{vrA&6o^=yhcixZ~N z&cF6;_23Q^%){xjd7fv6e%6#*^I*!mPX_mdSsHxb*%N&C!!_-{S?&9gN4NL4I!$ix z3BHTvw>@FXBi}DEt>swz6ml9N&E@W1Fc)1l+ zCjK$w6VTk3jFX%17%!CdpM>#D=E4#*d!sW5@fgO*O#{ZsO*6*57*^J;xor83Rclxw zDh*~zM==K@7^fh-jFbL+#wW-wOQ5Z^PTkJLx1swF87KXtjFbCIjFbK!jHAB1xWv;q zFB+XSRPSwI6Y!@N%Ve}OBA_+VN_gZ!OSzGENT0 zGENRAF;0O#8h{ts94#U` zjq$UxODVL8-pM}1#K+OitN?s2xI>#!){-dz%TU!Uv3>m9fhpUb;E(I}`sK z<2BhkY~s}!za8J^r7%wRGZ{xaUakGD1zI=8$-xN5$-#KWDbVQw_-vbdD`x?6u!dE* zf|=OJxQ=iC_cBiU2N@^*Puv{*YawXp3%3CH-;tjVz<*{u54#|UedVYs+6iS`*;oFx z*joq`ug`cNbdVZ=w_=KRbQZ_129eP$#z{Yi@jO|7C9HG*tR;_JfOAn6=6nWI z%LfvJEleU>os z1Po^@(wnP z#rOr(-|6P+lztoq``iNHy&JL4_jVyL~OFxCBi*yt^m5~!^@<74qE zX=DIikMYT<-z)%c+05}@;dmQf1I=d@{=^IoV4MOS5rB_poEk8_fVQiwMS-BF}Jm<;m}DG}MMwXpR+nFun|VU&c=(zmIW& zV{4QjhyD*o!4y9Md@Tg|ql{A@Kf^dR;9181z=mzT6<5dK4knl!?WA~b0Dh41mr?(d z0Q?KaDWj)>+s8lkC8hLdR)JD_m2pa`mgYYuD5JrQQ%1upxz|4Y`eCZ;Rto%hL&ghG zKO+Ed!}wFE-}NutZoj7WW`Z?X;hq4zfN>fVGa08bF^6&Lf+d}pfVyBgJW5oWTxuS$}a7R_7Vf|6vk;9YRNcdyglPI1alo;x!RyHn9nNE zG&GoT8j~X!r!n~;<1{9x`*G-68k8k|0!^cqJ;OM)%*QzC?`53yPcrURV^2*}rev1Y zx7!cDd%^^iqDG8UhSC_P47FvPGSr!I%FumYCZHCNV*E$U#6yf%#g;w7IJI~g<5TK5 z8C!$gOY_A`DA*OC!dr|Nq5et6$-!yH$-dUgugkm|U1bRJ7id%=g7HJ>xGv*OA{@g_ z8K?K+Ef}9@pXH(dJ2L^j7w^e9jfnw_)0h~_IE{%18K*HZU2!%3s0-*_!!lNZGPH(q z%Fv69Q-)q;oHDe}#l7nK45jE@mq2kRMVfY$amvtFj8lewVw^JcE8~zM=lIiGgE!bH z6O^KAj8le^8UF;wL^|Vogkv|GacXdv)_DArln*_-1g$2A`7=V{BPILY`#%aQNo^fw7zCnA135frl@eI^|hjBXXe#rP} z)c@zLxmWua6Fi6&eqo#zyH^Z94%Bvy@m0vJHhBC~7m$ORZJdh4$w6br7h>iz7~hAy9pf}Xb*qjAw*Fm1pBk^jI5~)Coa`q%{IBc(F08@;94x&Ur=w#ufN$_J0d>JE z0r=k;r|&_0#`plt1pO2jbtUQlhWZuje-hkehNzFLwR18;hKPqTPF-0q0B_{ay&Cm# zOMgKHZ_haO@c_m*#W?{EWqd#K@r*lP*MRsRf@iPAxde_>j6z1I`5C7Z_Le?eSl; zqf?PGK@K7qCkF`ucw@$?0X-O}Z))}J==iVbf*II?L97C0XgK4`QU5W<>FAip_#D(P zuHath@FT&>3W3AtVTJ9Cmm%NHcw9XvlkWuJA2Qy+ixqxi0&?&xzbhM{ z{RWJaeQz@+AO~3icn;&_UOyJ6Yg#!|_WfiCecQH;~a3AAY7|_@Nd{QNM*8g-AJX$HR&x*v07^gr>0`O-T zrv~g`JiVUXeofoM1f8%22Lter7|%!jF9Psy7^i?VZ)ep3m0dt74Pu-ega_cUjFW>l zjFbIN$ScSX|$-!jC>6@@K86Srkn&;2G8ujH8e}Og+E4;w?B;@6cPer~v z0N>B}3|rr;X z`?eqQjH#v{ttoR}fKSqk5Zj$rZaRAbJJnDtL|!neMDz?p`4J|k@6aA+oa~)q9PH(r zRU%@@p62oQ2fsm64)Qz;{n2BwC?5KHZ4|4QkNWA1zb->ORU%_{qd13&?+TSUo+=S~ zVW=$LY(;qIg*xF3V0tCUCoxW69(s2${Wz@=(ja!|7{NQH+zl zc*akoon*$zeh%Yk$E)Qs0U63?oW623fbq02C-6y(&qw|+<4+;WR;f}$Ttm1Iw<&4v}N_H~d5B2vkPWInr9PN9xQ%pdH&M;1fE-+5tNV&>* z83q(u#lNew@Lpt;&0&70gL)JS;#mdy6l*f$bT1*Dak{^h#W>wO$#HZ0{1WR#nClh* zqI-h*jMFD;1~5){Unen6Eq<7B)!@;}bs-Zx9PI?OfbnwVWsGMDI_q#wov{K~DHI5a=TkQH_N`+hrZ?mEV{VJ7ym3Un;J%Q)REI>k8MHao*O-PO9_=IR)uNUypD zz-eqaPiU%~4CtrxXsDmKE}(CziV^Xgo3|trJZ6Gh@WBn zBpSNF_}9prmb!<@ht`&-o`Dal)3-{$V{-a3=vBt)yO+6!@>c1O zZrwl0_$eHB2N=(BF58aKt}+2#t*ni2cq5o+A>ellU3Mo(8i*?W z^ywgIByUu)B1Wqt7)5xj3q)ly2C^cZ4nvJ2BTWK z?mTl(>9+@IL#mmpnk+8{S)k^eEIEZJ5c1oH^=co3hTN7Wz!Xchm z9p@G8FXFaJEdNo>stb=iJXOt#f!(!gR{fBKZdk{$FPjBhiQa_m*v^WW)gZGw9{%4c zS~d{<+&xm!j6u+}ih>$Z6$QTx{4bqeMf5YOMd%HDp9fpp^xG01sqQq=39$%E$xGoy z3OwV}YS=a*5A)!t^v6OU&hSzW$ zB@DzDj=2d~N}dic61`aJR)Q~7ogPj_P5dk2MZ^j6fehMro zqB=y>mLgAuSef2i2>g#37+~&W{TrvY1`jRwz=eVYIu4!6g2`Rv4cG^XY5Fsm^<7)_17>XoB!Uk&+q9Vc7Pmo7W4l@2UO)&4wN;&ZrB7y)hWw6 zTXlxatZjwGs`>0OMJ;$TnN?qRcSS*ME2&z-Q9MEuH2RaCTHEd%a`x5GWv zNm!rlIt%?TbFhFD?-h39)q1JCHi?ApOKA_Ws=3r}N>ZmvwTTd+!CTVCYD%&$*{HW# zf|!lflq7~!G>|IvQOgnf9Ytp?!a6Vp?9p))=jtiD5B-j!w=qJZ4GRY)hREv;0nn zkhCDL7L=6~l-02E{5KZr`594{v+n&Lt$4u7&6vt{gL3^pR;YBVX?>GdL|M_bZ*`=~ zW>Hp@_tu9^#S}*?z1bBjy?$!8at$C1$6f{AsRtGEB-rV3SMVEgur{!d$jW5|)HkY~ zhM(d;8D%wU#MULZ)5@kY9dlJWd`+UQM+|R9cr6iDB`0b{=V$>}WD`7EMz{{Wl-L4a z)L%G9XthKJ2$SHYP%o8cgGIpgsFKdm8x2VS%h^?=>4M zD|OT(0ZV0B6AP5%;Za(_jjUBEVvc;ipLI=76|!-EtFC!m3u-4f-eEm%mgqsLzFz&U zcT5>Gz?v0Qkk|i#i8Dq`_8lEyO%<*ObNS%GTY;Bj z?I%8UA7MqoNvvRm)e(L`dcE2u$gg21*Nub+E;JlzWx<0L3Pw6&*j2kY&hheu^H?Zr z6d1^t^+til3|XLd&&l<$(?6P4`RFNYv^4-8=uj})Diw*PgXcGqb;nrc^7}DhzOJk{ z)`}D@Wb3h38a#|+jM|Nsa;$Y;cuNZwM#9f1uODYcMlZA-d$d+g02TkAk{>B?sSPRy zaD{lKys5-%ZQ#-RRtTII&&jm=LA(jY1DJTLEV$oFlh02yqQt?{mls7!YmyOH`s$+E z;-o5uor4PMxmD#@ak6-QycHp2`~%jvLGWPpaSx8kd_al`)^gFgbmG!TIFL(^ERE1h zwbJ~O2>I0n>(0`dORLKc4_ZkzRrK_zn8s%5q@@w^3E&MC--8ZDn9d9JmKlz{3jO=d z(wyZH`czY1me#fe)guE zMaqt6%t-lTkx?Cfk=`~Yzc^zi`(B@HZ8YSrjYf4Db6!;U!g@(7#N!rkL)zV>I33q` zL!yG8R32cn=XThuAYh@Z4aKf*0I$`iI5yNSr`Z1;uIz`H_=&*QOt2nD7_A?aAyuIc zI_SpqCm`?5_{&)C&-gIZAB6rZT9${7$Fd4zkWXMd9}PXs_!Z>y7+-;QmJwGgWYw}s zn9|iGK;F!7z;lc@#x8q@@x$o&1ICA;{%4GPzr~17Fu_oC{0-xm(9l`NXQ2K?#@nL( z-x;6daQH+Z8l*lRfGw!PxOzOF+G;SKgbuQ5PmbSq>}#2AIsk{{yFMj6nOkm7rcTgy}>G+#0tUK6{Pz$$3i;_-}=*^UTn7EWgV5 zi&*Z0gN!mk0o~5{F;!N_ADvvN0zDu^vI>RhU<2dhu*EMkJ{k4*Fs>FHYWp0xef*PS zN_AE2JK}bvP@y*Cd(m+{#w~Q1!Zq}C9K@8-cd)^Yy-YxcS~5M=|?ABv6m*rlvE9iFXJZP?UK@$0GpTVKXW zf3Ta&@Of66SH(oPj#jwDivI%-w&xk2g2QHui!1kE!Jpb*cX4HhM&oW5SNbq(sP}R3 z`->>Bhq3$=;-a6=x5YoY>M47VV`|U4xMRpx*XVN)N*pSCJz*#HQD?Ws*`089!Sm5o zj#E=B#do!KRbVe-=2yD7az*;jx_GE80&~$yTnK+^JK!fi1Y%*yYxAuc_Cy?S>u6fb z>dp(*d`!6w@?2a6w9lrRHV(OBDv$NB(kjMjR(_6g(05KmZ!p1H9B-d6PLt+I#(&16 z@(kk#(ax`o|AY@~=|& z5gx5gNr3z?wxA8;zwY8{M3TNIMAgE12li`FzYcQe5FET1rUq3l9ecPft2PkL zcXV;Ley)qFu&91N#$%Nbwy})EV|1e8)yLLxY#7)^rw98lv3l4Y zzZ%88++wIv4L@djH*%*(4uMs><8v_L*{*7;CB)~uxO({snk#0UeqCxca_so0tTa11 z`iV#S)`J~9n9G3s3u>e1EIEzZ4b|Ypb?zx_+gj90!)tt0n|^3F%gyD8rFQMorC2*1 zukY{++1#X+RnrY*xBQ=UR_6PmY-JrQXEO~xa6TP8>nbhz{Kgf7Zl}sH21389Oz#| zPS3q?M$&e0V|T>+^_(a!vTB!*|Ka8`e3_MIsa&;*m;3g>CGa83aH6~~-m%jUk2(r# z9`ZqME_Z_+H6oW;OYK}-KrMkson2d&F1NMz!_MyLp_q~mZY^+oD$()X#l=;sNWZs> ztKf&%cl7UK{5#|$7;l!O$%j^0jqM;#VG#I{eP@XX_7)~NMwhV46x`D;u7V>wG|^DP z8aHt4Y{Ecu3W5Y z=(ujo_!Z136on^LTA^MCstaU z?B!({1~~{%wUnPf8#&eKWAVhhtK~jyV_o`T^3XFlc21!=`T;VkwiK&va8*;eAU9hX zKY{wMxVYV&Xn&WBD?2HTHTlRY=r&7kSOwFUCC{ybhFUUqH6DQ}DJpEZPJy#BMb-y- znVZW;p&AT_Sx$aC>jKs**3FfJB{1qmKU$MaZ)93h*& z1$PSXe?wHiO&P`MwPLR_Wpn9WXGOMk?h{vj0E5KDQ_&CcXR+K{lldDg^`RYmBQdEL z1mHA`NdF#ref#coFs!=-*GG2z|PXh2S7$^5v zk;`>|SV6-Jv81W!VWUPYb&6VW08V$ENPivb)8!Q6^XPgG>zgUed1?DX-;{B{+qqayvb_s!ZJ-lRGWC1?qoCG*~@qS zv_kKoR5iy?sS@#Q#woPC0KA_r%U*zc_V?m`Bz(FDzJ9JxcJ`SwSv^V-T@WMxl%lnI z>7;ED^7|WBXzA>2L7C;Oelu+J?f`thE{CoM|3{p?oPN^^&7|@2EvrQQ9OH9@JaW^D zD80QrC`QAXlLDpe2EzxHV5|-bXL3p;-SDJ(l*oom{{l8B<1bw1{0+XxPh+hsldG`^ za{1B=Mv#7wVP{=F|2HeNEv1;QAyNdCV!Ag(oQ}SyoECXkFi+H?=NP9J(XAh{M=g4t z=@X~>mZVQDw69^Rn=&MzfWKjeDBxcL@GFeJpbWz1eAA?IdV3XlRXnLVe&GrP^>J;} z?&GjHKLxn5C}f#lCE^asKsu9Ci`oU?T^XkyD}c`&!B^7gmKf!MrrF7?8hs36CgXIB z%nQJmFrJTjSn2S}4!9Quv^1rF=(yR!3=!YX_)@gei1;*`}WNEOf8 zmU=n6QfGI<+13A1$$aB~v}BFaK^v;eL7nv|x$b8pNUnh2A&|XCo7H@|SFJm0$W_l9 z)ngvU)uT#g75IyXKeb)fN(;9}3TX86@Q!xRIx|RpBQC7BBehp!N*z|{Ig5=5Q7+T0 HDr5d1I&xtc diff --git a/cache/test/tango_cache_test.c b/cache/test/tango_cache_test.c index c24ac41..560673c 100644 --- a/cache/test/tango_cache_test.c +++ b/cache/test/tango_cache_test.c @@ -76,6 +76,10 @@ void get_future_success(future_result_t* result, void * user) void get_future_failed(enum e_future_error err, const char * what, void * user) { + struct future_pdata *pdata = (struct future_pdata *)user; + future_destroy(pdata->future); + fclose(pdata->fp); + free(pdata); printf("GET fail: %s\n", what); } @@ -110,6 +114,10 @@ void head_future_success(future_result_t* result, void * user) void head_future_failed(enum e_future_error err, const char * what, void * user) { + struct future_pdata *pdata = (struct future_pdata *)user; + + future_destroy(pdata->future); + free(pdata); printf("HEAD fail: %s\n", what); } @@ -204,8 +212,6 @@ static void dummy_accept_callback(evutil_socket_t fd, short events, void *arg) struct future_pdata *pdata; struct tango_cache_ctx *ctx; - - pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); do { @@ -230,23 +236,30 @@ static void dummy_accept_callback(evutil_socket_t fd, short events, void *arg) if(!strcasecmp(p, "GET")) { sprintf(filename, "file_index_%u.bin", index++); + pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); pdata->fp = fopen(filename, "w"); pdata->future = future_create(get_future_success, get_future_failed, pdata); - tango_cache_fetch_object(tango_instance, pdata->future, &getmeta); + if(tango_cache_fetch_object(tango_instance, pdata->future, &getmeta) < 0) + { + get_future_failed(FUTURE_ERROR_CANCEL, "", pdata); + } } else if(!strcasecmp(p, "HEAD")) { - sprintf(filename, "file_index_%u.bin", index++); - pdata->fp = fopen(filename, "w"); + pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); pdata->future = future_create(head_future_success, head_future_failed, pdata); - tango_cache_head_object(tango_instance, pdata->future, &getmeta); + if(tango_cache_head_object(tango_instance, pdata->future, &getmeta) < 0) + { + head_future_failed(FUTURE_ERROR_CANCEL, "", pdata); + } } else if(!strcasecmp(p, "PUTONCE")) { size_t filelen; p = get_file_content(s, &filelen); + pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); pdata->future = future_create(put_future_success, put_future_failed, pdata); tango_cache_upload_once_data(tango_instance, pdata->future, PUT_MEM_FREE, p, filelen, &putmeta, pdata->filename, 256); @@ -254,6 +267,7 @@ static void dummy_accept_callback(evutil_socket_t fd, short events, void *arg) else if(!strcasecmp(p, "PUTONCEEV")) { size_t readlen; + pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); pdata->future = future_create(put_future_success, put_future_failed, pdata); struct evbuffer *evbuf = evbuffer_new(); char buffer[1024]; @@ -273,12 +287,14 @@ static void dummy_accept_callback(evutil_socket_t fd, short events, void *arg) } else if(!strcasecmp(p, "DEL")) { + pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); pdata->future = future_create(del_future_success, del_future_failed, pdata); sprintf(pdata->filename, "%s", s); tango_cache_delete_object(tango_instance, pdata->future, s); } else if(!strcasecmp(p, "DELMUL")) //TODO { + pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); pdata->future = future_create(del_future_success, del_future_failed, pdata); sprintf(pdata->filename, "%s", s); @@ -290,9 +306,15 @@ static void dummy_accept_callback(evutil_socket_t fd, short events, void *arg) } else { + pdata = (struct future_pdata *)malloc(sizeof(struct future_pdata)); pdata->future = future_create(put_future_success, put_future_failed, pdata); ctx = tango_cache_update_start(tango_instance, pdata->future, &putmeta); + if(ctx==NULL) + { + put_future_failed(FUTURE_ERROR_CANCEL, "NULL", pdata); + continue; + } tango_cache_get_object_path(ctx, pdata->filename, 256); FILE *fp = fopen(s, "r"); @@ -302,6 +324,7 @@ static void dummy_accept_callback(evutil_socket_t fd, short events, void *arg) assert(n>=0); tango_cache_update_frag_data(ctx, buffer, n); } + fclose(fp); tango_cache_update_end(ctx); } } diff --git a/vendor/hiredis-master.zip b/vendor/hiredis-0.14.0.zip similarity index 75% rename from vendor/hiredis-master.zip rename to vendor/hiredis-0.14.0.zip index 509f4205bf25a243cbd0e32bfa81097f87e2b6bc..06b0892a4cb20f7fde7f433b696a81e7a18af346 100644 GIT binary patch delta 17380 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
`dh*sGxKKfw3yfeFhQBGyfm83hwkBI&oETt2 zf?+=48wPP-te2BXhXiy!)p7^g4blv1?Z&Qw0QB}EZB1e}4^I$VEe6kLW)F5?pBa7k zbjIuuHMfnEt-*Y@+{MI&Te@_%SRP9C_x5D-GMcg%cFxu>VkBv#QzO2%Nb3KH7Be3m zkVhjG_?-Xhq(wSHUd)2aoZM#y$6g9^$ER5Py8PXyI}%|x;;jIzOWE4d%IRU_c4U}J z`j56?I(gf-v3|<~BM3XS2pj%Ez|9qiTSDI=jigu88n&lDTy{Us*LT}uExVT4+f>BS zAEvl@X%gTtzQV|^wJlaLMq2KuvK4OGQZVbIZB${fCO>udR+dgisu-hxY4cRK-N!54 z=+)9iDwW}wpfMxP^N4pjZ#?Ts#M**w6pSVvFEU_5;v=G!JSgwN5X`0dbAe5)kgrBa zp){$<*E?+x3N&o645sqqw$R+~cACt@LY$a$8@FKxZB}eLmdfl4hH}42iXXIldhN+o z8jpIE*HB`?h?b%*QhZcYe1*ey>`I2qSxAqeYHPOMAM6ZvLf-PYPCLNKqTnHJ7~ID%RsF2u-eP;I<>Q zKBl7?AtdP8GSGqAr52;!(Uszv#~O;YVZ6Y^exj7W-#X_>g>q&fb8o1q14Jm)4><0x zVcO*WR#NMt15cyR^Bt&y{1wkc&}$U3kBvS2x75l`7_t!znyKEqS0)4F4VwhT%qCj~ z%fiYEZ{0&Z=}tG#?*=%BN*z8}T8@6YIo+^zqu06Xvs8M!($Dv5HL3rLsf!>}0b0?_ z+?f!5sT;!gUGPkn5ZoEJUg3;EXnu*Y`e}vKM~48S8#>9rNhmc2PzpOc>3A^5!z=J00v}Db6YTd zGDKBEd6yU!A8!w`VJvP~`dA6h*5R6=#@@i}Z4%jE2=lKU#aPYCm$d?GTx8iUY1=1Y z`?zhy{kl{eb9L)V?I@qludAfIO(z8t;ycI{St{;HeE+10xclWSFp0T!BZ6nId}Ql& zd1Z6N>bq`-jCtNDoaY6*pND@WRik#45Nluh-P(eT7VRaI{G<%MH3ME4!>ZozB()5y_5fJtPrqZn)hk)o(!=_=EtdT z=}YO8jg;^&GD4OHSa(Uvaa5a)!aMj-FmY(OH^bB8^#s39Z|ykXUACOeD#uC)`-UJr zA#Vpd`2C=V%1}6b-lQcf|Apzv4J~gP^H(Xm<>kg@Utbh)hlaN5=<@7x0dbf2j#GPzNAjKlJqjiYA(F&&i{M9Y&_bndjTI z1t-hPhEY~Mo4^xKi3ld_z>4y4mRmd5Kv-;^_e?jKh%1|Sjb=d9pp5Ym8k%*kUL}dK zadss00nkRV)D1^QoZ9}Ei+=CM^f2JIeo}WTX1TUOr zb*H946wkm0L=Mg~(FqbB|sIv&fA{utak@j!A~y6l zD~BOmHTGjYyI^xJ1o-dc9os$0pJ-hz4szZcgg8=E3+*t^yqogYtu7*nG8H2NirF3` z+@J0KbDAby#h5=20|r)x@qe6;{c~&zIv>+?c0&LIK;9qM{`^+;YQ|={`>AJWbNYh& z2YRZJoo4Gs*cVEbq9PO+k+>x(PXevfL(<}(FvbH98P?_<^ApCj(I}&^nM9mjlj_g% z(#38FPkRP~Y80D`E$ZcLHrB(4fERs3M8He)7y60TOFWEF$zzHpN6+C7-ufh(1?=vhDiAD zsy+iMs*h)Bu~qeBbkJmFqmp5$xGPZzmC$7d_Hk;gt=8iXW2u)=F`k;vjRltvD%C|x z_G3c?E?N-xRux)CC@QSs#Vw`jv^9H>zl}1!z{=Cn&yXTVP|+}>-)gCL`5Iu2vD!D7 zOD1n$pJ(wysf+2O{<3KEViAKAO^GoHG;|2i4)SR)SU1;Ipo)hPMkR$h-9$RR4hs~` zxz9)(xY{W6T2fhdMLPRdOZofY3s#DszGiDWgP{hK=n)=A&j( z%{xBgs%Jzm4>d|vrcJRMHOHyLb4jqRn2ySQ$~iS)84{fEwiA7&%BX8!>V4rUfr>i- zzToq-&lS`#_#%?t8+(ey;N6tI)RK<^r-o@n9;?;Eo+aa~qOuJj3Z<}-NCOh_t9uK( zB}3g(y6yyT?%^aLP2KKr+YwPbmA&4agcB-nWL9mWvfE#a2=k+*^<9Z+W}d8QGweNZy!Ce+wCwN2Hor@as49D7L%J8^c+HH1|tstL@$+a1>cDY=%0WSu; z#Z?dZzzVZz=Mj>C{q{&#Y}JHCFhAUGY}4O8nL2KDH~Mn(x)W~QRewe7xH}DIo@l$& zU+$o%D(T>3wpT6$Cvp-XS_HGe6kP;y#;rNQpP@@0W;Q7C*{30riF2FqV@eTN=F(^U z-^$MTcUgT_VTOYH+J^J6hezAncz_OjRePe|9gDC}U+_*phb#JETDeZ=KKNzK(~fUu zQ9H#u`TKAkbC092z%uTtJSN-FlxGs#qzU18CxHhP=WpL-D5&99bEK-4S*MqyUwbH+@j!Y4LnDWpU%NT@BakAXGAbB_@`O9~-nj zRl&-VDh`ra5N`VXLneRdK(+>cvgb(rn*uP;=JdTXd+yVKmnDoU6}kQSE_uk{vzhh; z^JmQj;NQ0-WE)h+id7RSEgFQVb?{aKd9^6&5Z;a^bimS_3A+x`BVKg@^Tx;4uMu;@ zo)}S5ltnWm=&K5?U&~+?AOzrL7~<9;9jxIZl&=w%=I%U~d10qdkc~ zRa>MYV5gH%7u zge74fVvxd^pp!xL&~DR1{=j5jX<%PshD;F-RK?CQpUQ2QvBfaK0vbUOf9|hhU^>b5 zz)LBzpSa&ZcF<$Y78u)p1jRS8T=LY^U1ld zryA#}^s~v!E(6K*n|s>wOs^Gtm)>G9&igBg+JL)^BYELpO#m{(+ zV*uh?t@q`#g@`_B3Q$KMZ~F2_z6kx-gGiUznquDN%F9 zI0V-->^ez#Q#2T`yZ?!E2nQ(tpe z+x=c0m0<7+viW8#5fWG>&y^51xFUgZ6J@X!4`Jg{Lh$J0R+RGI*!dXoaR|Gb9b9-s!WxSi)p_pbHiFan>sY1PM`?wvG_XlS4s|1Z+@g-6cE z!k5_W47yRm1DFKlbTfq~tkfq~&Yme+(O1m(mU)$>|2OoHwxA;3;Qu8-gK$wpE(8_Ew&=grU{CwM0*&1@1mHa|tZ238 z`fYUW_|ORJsjqPzAKG@|i`>1>u!oRa0a!~-6xX&KB90O(LfwI=AH?2&x;r7fJCXH7Nx4eBmg!v?U$R6^>b zZlqI#Kfgkg=Bu}~f;5$YP4*Q68_T>X6!n8S1wGM%i7orL#$1%B+UB)yC zv9`;nO0n9MQe_h4ECU@@odOISNx5~6>ng%?!~k{`l#5^bK{G^_QB$D{h&^P+Gd{=DotWAHZ9t+q%4M- z-YLObQQ`Q&6GyC!cV13gw$~L&WTXuFQDh>rsM`r;IYTcDg-A>xLDXQG4eh+{_XW_>ICq#Q>8TUxn8hW{mOrB9$&KDj(~`3qXA6{$dK z^YnuJLg-3vVDk|PCKT3T5nBC|p$w+lL+HJ?N%M;teV1(;3?~dF1}+#+U~I6NyNLA0 z!-V(W;KRJ)av*t0xEb8W+0|mWx2~`u_7p*AO*`y8;Sa$V8$Zg{#kAKhZWi4ZE@HKz z3Hy-^I8KV2uxFN1r5ysM1jrE>CadtyN)EOXUkfufj{->;8z(94vBK9&BhWf^fP79u z9Ju}&&qlsWw0L8k`iHviB6+le)%7>o-+U5P8?>vyTW%?-QUqVQ05Qxi!mjVz9-w(M7 z5Q!5`$>Yt2%`)MK889Bqx31TeqF61w^+>fQ_@QBnO$)pKfe}ZzA-&J0M62-2db0{6 z5&?@iB*fYBnVf_l|MJK3epg2SxvcGT?Mqyg3{6I$!#wu7`_tXS-~&yV$ga$07u?dg zE>$|$D$6+6w#2p&@r41CrT5_<`0xZ?g>>G~T6#(axh4%F8&I$c7)JGA;0NZ$X*qkf z`h>rEEt^VE^inBID%q&%;;YH3VODu&DN7Rx^-nz_B{z$bRkg3Qy5OjhtZlV|I_hzP1=``D- zQ>8$4ozJ_9#-7nREE>K@IM!2p{dlF>fVJ&77$_l?Ul*SLBV)^4>6I_^`~}kn&>$yl z-}UPhu1wQsy7YRvi(rZrYD%Mu$m14ceoSGLj=V(_cpuY-bxf3u&tDP~Z1Vsj+lW^X z8{w1!`OrcqCx`FEBt{~)B(wW*+^y1P%7sQnfRitbsp-g$DXp8-oAYH-gs@)4i!o^r zm;g6qPvSmDkzjO#!~VpzG2cMi`2l4y7q?7gmP1z zE^zy*BtHur?W}H36O!-kNtaPrkAR!131=hxYGw@Rk7AEYkVZUy>z!+bho^wZ<;f=K zBG?@-1~ZyVU%=ll%2U&w@HGFd8~PImi9S%9UNHE*6f58o=*_`BZ~w%8bR9b8Ki$!>gS_V&00-wsKx;&FV&kV%M(xgve!pb?mr z9D)R!@&2p0JS*{eWT7ar--wlhs+o?z?P3vs=!ExvTB_z()O_Hf6>2q|AW{yN9VFtSFeCL`A7t-OJuZB)9cYc>$zpg}pzVTt>G#Ed` z#xP#CUIcTr1u3ytx+nBfd?#!W`4b$lqaPDm0wqRFbo019aMRWoeON6kbL&(YOE@X3 z(@WV`($|{aLpZnRZezIigIGGkDb7?L$B~&ECpWRhbOhE*sXPBB{B_Evn5}5fnl#CA z!XMLo-H5T+@N_v+*MpSs19~}{ z@E#a3DQ7f@_^=(;5q#@x=W6lGoj0crY6xbIX?4fN`sJn#QE1ZnINz)$ac{vgOyfMQ z54pCTcBFk4lanfSE~(xJ5|toCG;yiL?P@KI^G#RG@lC9acU-R z^V=FO&SQ_z@-f~Esg~2Z2;cy?>a?vHYvr9fmX#IP*Qy$A)bYm@krvGU+HDroiZ|fq7EU|HQFQ>&=22wV&W6b3<8XE?sc)6)h$8Ix-)Nzed z81^b%?Ss{^Lg~b=s%bWaV;k0@In!}F{fv;{Z`YgTb28-KPY8j zxIBmT#7k|nZsqJo1Wtr_VIyutH}Ko&IAr-xdv3>HRO8s4Q!#`?W~a1B&6u0`v=4ST zr70kHexvEs_@>OyQ$Ngdo5F6$euIMXGd*JZ#Roj!BQB%mIUX`k8 z=F;SkuZPI%hHJ=4zOV)5u}{=IT@z?0J7$PJN>VJ)&xhLTx08*f}-3cEa8A<>r`mXaus+fO!IvIs*w5#LUvoXouTze@|dQ%<1k|0Y~EV&$igQ& zKq2OV<|~|F?df=r&sG62^qY~-=1_5q($A$hy+4NNrFEZC>%94bNeFoxnE)`$-JX?- zb5;_5u_jscRXD2dax%sxKY>+=OKuM@=B5grl0{1DLkO^66lf&V=4d|(Kr1r@nJbQQwYvk@lEYn=d1O4LhcEQr^;dUqzc=fDLb9j#OA3(Td) zQ3-mOjBK}E>8f(1&EI{hOa})rmx z=TI^V>ZK}w?&zq04~adRm}@BY1q^ytpj?07qCXxV^~G>+0dL_vx9ZBU$ettL9ct1X zX1fZ-6ZLU4Y?>exjgL5Qjff|grQzq-+%PZE4S5uR-?Ibb(c3ckyo&gO%s-LE!{=u; z8|i32r&Ey8>NSW0n&L`Jx}givG1%2;zWDYHw?TcU5^H+#I`&JTkl4$@Y|b8;OpY!$ zzpFBps(qz6HELMG{ltW*^o5vj>lVjIg_w@CA1>&_@)d`*AT@T#Dxy1k^{%NHyiSLE znZUnj0iiHcu#`(_)+yze+q17xB*WdcGE_R*M}28xBlvWs=%4YLH%RXY0kDz%vMd~J z;c^1tzuKrs6mU!xPbILTzlj`D+(d~IRo=QZH=PT|jA1TeQ>C=LyA5Mft#d3>G>VGzWfSTakHYTA){d4hArMjH zMVsa!?DZEO5)sA=Y=+Ot*OL?#?ZL4?#a_)!s&IfSMB)Xr6lWf#czynQ7k{dT`vZ?8 zwJ}h;%50^2#3fU7?P(I>)h_3^{_<2qj;dSh5n60Gd`Nepj|5~%MYi%f0c@DPO1|Al zHqxEfqE5{nOlj$XK`L#n$Kz|+*qvuYyOeZ|%;tN&Dia>GJV)0>GE~9B%jX7tc~?OZ z?EUgXF0q&><8>j-s^W>6u!+$9`5a*c)mT7@?XFGC6RAZl1bz^XB@ z`P^W)YmR93Ep549|275n%QfAAcdZ1%eUvAfRLbkfwXMQ+G~r=^OkH_HC7K{^oY}(F-mepCSFyD z(-AF;GZMR7s%w4o2`emhkDf>4rYvEIz-h9;3JYs=r;$Go^gKE;5^r#fKQm)Dn?(Xl zbYhST?`jwjp3NcX$(!Cxjh{fZ0_PjS+>HI~Nl#juU{ANmaxvYmpju;g=fPbzr7VxE z?9s-|N}4}YX4CwgOf#cP1sZzK=k=Ou{XEUMAC?Kv0l-t8j?A(C8JNIIr-aOgLHT2 z1Ba~99dcLyD(}m$cF~=JqVbtS(Faudulq3bnG(FfiM0g9GY58--)7yYpOJ%aq{O53 zqua<84^}#3d?-JS(bbA}*8*M!lHT3;a0O}KySU2S%?Z(lxA80p5T%`$x<&cUJVnVSQIHQ$XqPA5JWHT& z35Ij4#dMNuKS#iM?qutj^yGPKj2dOsKBe&~6AaR+&@xj@6arQ_*cg!7pN{WM`e*}H z=}jh*Bw4qmd1kzmHlo+HDWX`|g^N>P0g{n&M@@l9UgZzQd?;+w=ab<})Nq3BNk}xJ zNGhMll+!%c%^*g2XGKd=DGDt0w*uMAB;CBfFmt6h7}Q=D2dO=a(6}xQh&_Ta9z^dZ zg9UBfvpOXb33xl@Lsx)o5O*sG=|^Y7h6CR^*JlXZvaV&uG`3%waujzn*^I+fZz0L+ z=Oi6}qO&uv>G9Ci+%pg*F(?B08OT;?@S$A9~R%_fgl0 zHflr*D2p497j@2&wU@8O%K2=7fiuLNBCWqshcl*24fNP7yj46zFwWe z(fmYyo02)`0%=;uB>xlnN5nNTM1V!OpQDfz^Er7WAhCfCBnSM*C?v?KzLk}&;e!Sn zL82=aPUqI79$AA;jM^pRuZ% z07~TFAQfe(pHrW)X&}Mqm-j+V0L5Q%J{<4_8G@YO8)DwiB7#1kYY|Im0Kg*~2L17` z(a^uA41ap~4aEN`gZ(+wiT#rb0Q#QkO#=Gyzj%I)c>WW_?`UbY0k|}ppjG(4a6d&f z&_#WO3YPlEgL zPt3nc^*c%p9gwdA(5qR0nnsmkVm|Wq=fLMfU!x##=ud*!y@$S}?nC9cd^?K@TBkUm z8PjKfggQa+Z}>mcqyNl;K1lu7dI-@4;8F>LZkRt^|AYNC0s07spasCCfTwzdV|X|V z`UthJ3!wOGMeF}D0{Xxd@jlVN$3J7$^#BBzzZbOrUsInC%wOD_|M@oD!?Fg5J&N%c z%YUt!LOlR3Wv$#J#Gi8b1Lwbrh^P<1B{6;V81|P2{s8fF?DtRo`(e1JnvYoiQp5jE z@~0C1kObc1ze)Z``O$r@VgCsAw`}_#cbKOEXw?@!!o=o*o*94NATRGP&Y#No!$6&! z{*Np8|9RK`sgXZqC3F2Z>%C%5^mkCdE?S!*DE=h(N2VanobX?!3`QVR{5St) ziiP-FIe!q|FaG3vP@&f&P_NM=egtEXsfhO@Q%>UtQU6T(PhtFF(k8x-;P)~)!cUp} zL2y55vQ6IJv4b9QRv?X??2pID@caLw`R9WE%1zz`6tLlkf1842bBu>iJfZum|EFsH zFy!^1e-ki1(9j>m{FCQT0sSFQckm;g-%qpqPT}7?e@f{Oc~EozC(j>u&hN+muqgod z*-6DC%{m<#1jzb$20$z{on1|1IND-E&zdukvSfL{_5f$0Dk_fX&raUVFKMd8=!j!^N)L{Q2r6g o-woaamY=<{9 delta 17509 zcmaicby$^M^Yx*T2I=k&>F)0CmhNuh5Yi~!ozmTnlyrA0p_0;q#COyuP@nhrab3sD zKW43&J@-C0v)7&>e-SEo5eiXB76K9u@coBXPb(G?=c%2si>sM4le*dy00i2n30;Cu z6Y&{NxZFv8U2+mJ=bCIFQz_5~2Y?T-v~o5xwQ^zj3&Ut(+C`bwYzp^!KxMbaXfKa&Z1*<51I%f^o3LY09^)a5gF7 z0sx$b008EHl?7}u4(7_XzH7k~j4E1-{`wqne%eJ*45$VMRUv*Rnz z5>X?N1lQ~05IOHfizgflwWQ03w10u#Sj9nQ8w@Z4n3x-02KOSqWV%DCOnu0Y7NjNc5hp^v3u=jgj@ya`{}(0vX>kfwv)>8d;~%5oKt+F{sW}4N!Q)3 zmisj%&Fy=b;McB6x1Z1N){&!q1nYfJy#-TD7}9U$>ZJ;-qXfBTrA{oHbfiT4@hq;W zQVSs_>{eNzN|02N!>wrW{9@@KEbK{4my7yxW&SLmd5kb~V6=q{3L*(o8NgO*b%ByVHv%)cKst8ni;QMp9jCU)@X% zmuQ$Cc)QjsKS=oBtMlm@JV0P#@ZF{p^7hDcdl#+ja%MY1& z@&t3(&+8})tt@B;GI+CZu1sh(N~Q_JO__AWJ%U`Oy89|f73VoyEN3>5c{{Zu?Coo; z!^kh%!Knt;^kpzB==pRItmp|2n1OL0IrCO&A^pYW^W0uDz)Ty3kXH(X=>V*0ZHl;N z@j~3&@Z-J)V9R*1sUg`@TDe?1z(!|$$VF&?LpDn^`gFB%m=tEyD(%k7G$34@OC#2Y zY>Dzd`!Fk;z+JkND1$K`*eF_dir1A%JsP^T@8`hAvws0>beLiRYbHEAe19bYJszlG zA&c)AeMpNOjk+WsLKU;khf^1Kb#B^xgKuHWxW69)c88MZW4i}v>L{1ID}YRIB8t%A zyfGB7?)lKA7 z8_x~T)VETSMs;TJM8o7YF*jA~gmHfs1on>fU49gKj)V&x9$mj)=`6hG%bRMRv4Yn; z=Hi-E=+&09#~VL%`1WHqgX|COsXR? zk7Wrcxg$JWnk8w{phwrkTPM8AjEAPul0D6}x+PFNo}-&AN=&jTs%k5;rs!YE@D{kZ zd;c|v8~Gva+a|ZVX4!mIG(v&IL3N`l#frkBa`K&|IKej;J7A7nH)2z96)Tr#kxs#0CVk7mmsk%D8o6Vbw~;;cUf$(|OYqW2&Q3 z*2avR+v+meFgqcGu&{RTYz~}^&d^6j#P@m()NH~`4@utwcgj!!`Z86ZW>3^ z!c^!I);{4-T?0x6f1wuwkm^(!qr#F}(u$CiTam6@@G~UaG$iWHQ9cCI`Gn9M@yO&2 zL@f-iJkMXa)%c{q>Pw@6AGtHTR^)IUU$hc4w=o9IP?C+3{XBkOj3=bp?H->iAe6$A zt7LTW=@X3oy#>zVPUqSRAyggK+%K~V{j_U+B*PAIt$x4&4D1n0%*2PYBmdmo&(o?v zg;0%bF3shsr~a;E=X)H_Rf%AEcb>*TWbx^LpuBLQJs+FgV4IeXlUYMpxa>ToqDRx0 z?myxvVWRV@xIl8|kd6<+JmPU)PQ=w)WL(S&qH00OklPA4jO3@dIpaes2onl*{8(Rz zlusyQgv$r)6@6VjA7>uik603KbSg5Lk+&E&X%Z1 zB0_U|Ngp@)O0@Cg^D(kz-GyQIsdh?wh6Wq!Qm9=0d>-{l*Z`k%q8`;P*;(scp+0Mg zVwPEVM7t7MC^~r*l`%O{JJM<&Y4E&YtHO$f;#>`2SE$C4wyB3w%_q8M_HhOQop^AD zaQhtO$`v{9G58u)d@JZz3YIvS6yB$8PS71)tz&O2?Pi&KsmY9{_ZZu@y!xJEsFyfH zUt(z3k(GCwo08qt2go*P9Cc+nie0GMvd}-zaZJ}&OBf-)tKL>FPkfsRc%iX~T4Z(* z0LUc;^6}O42`(RRqAQoNAIx@P`?d^7Y%pmEDAAedfFCh)*kc`>zwEG4UD_@0BD|~c zeQGNKC0Ju%@J_qjj2}bpf^W(Js)f5>YwC0z0@2ZKXyel&4 zOD@L4Rl%yR#3RoRSO~5cQ!|xuyLXalET%=(fk}ha#4r8UlkD5bFymQltQ6B zo3_D8lJ~_`!SKpd^-@#)JcTsCXKJ~a)=GXvzn3zB(2p=qeT0y#k{u79PqrJZ#7T-S z{QA9C1=$Ru-sWoUTU>%1CjXX2R0+}(38Ln!+Q4tM`^|jp<1lZm(`_;)kQ5eAd~BBU zUjaMqM?@J+ik1qNy^&0PLV0{@@Tfv~UEQ*2pNZBPVqGS%Ii1$P{ z$qbFXy8Y`eE3YEzwNgWDRS^_1+moXG8TAspgxu>Jpj2^BWgSdv2gBuRcz0iAhY+WIjDUOK?v>Om{|LE>o(pU{DxeCZJCy@!EuS zSdzZw^qE?Oe9QbYUoOn+<7)zr5qn+@4ug6_S!ua=Uw#c!Av8s?RvL62WpHfZTV;G~ zXz7_(!n-1~hl%o@XyAoh)HEpx(}7MHt(tEbI-yxep2W=G+SIR?XRdT;Gj*#K%0|8G zS>gD`43}wJu;AN5Hz+7@6AS8n5b8MU7vtXEOPD7Wn?oPcyB} zy=gpKfoeu0)WBmK_Ymu=M1I*qB>6}WbUa}aL+f&K6?E(R2#~?R`_S^e3l=R66k!B@ z*~k~7uTt^-8)ncj3oUf_%?vDE0n7NB11%*_Pn3FGomsKT3p{0xT{5YGpeId z1Fw$+I9tDCcscfv5QbU1XWoXfE;v?){^+0)|BIcZ88u0Z zSm-7ZNiK;hbDRn&Z69F$H*Si-S4Z*(E3-5YJVc7FL$lNvZ62#!i~zc zQ(dg?FJ9Vx(&UG;^9pVnF03f%WQ?&M znlVmlg&Jn~5UDk(n1Ue7M}%$`#Z!Dhu|?(lC80`DvyVDuiXj5QhY`q@tIQhbEOUJD z;6!3q0@L6T0+96v78ubLZm%xd8LN*RiqPw_tNM~2XLn$Y6~{6{CwdU{EWKK-(Bk8; zzrdN}`3#%YJTb8r-e{|%czL<~AqQ52bhS@K297Ss{C-?)E2N?D?H=M`MyeCzsU+&X z(m28#&7v8}2F)E1>>Cm|r6Lr*%J%+MA}ilJ>HsASJC~gVAgNt*vgDK8J?+x6_ec#d zQw~)efKG2q8kf30DL2(FdgMBxn%*ih_9HckcpQyGicR3>*~!g(yvbDkT>a%X#IG?z zjag!;M#{ds1|Ud6byHKe9V7p_y_h@j)Ic4{>_lleE9?WuuxqE>vC^G&(t5wE@F-UQ zv*>wMmvYW`ut3Cb3%r-iNppf5HPM9vci#ZJ=@weteGLs(qxatDob8xZ4?7JsLeA!d z<);d}?^)Z3Q|7|w?HqhakhI#Nj@-diQU@{*#+cawUW1ZwSsi0cE$foOsi`-uOdDlm z>+N+2Y%hQ_BswR;K2^!%(rFPov z8pk#|mjV)aXj@(IYwK*hI~6uelIUBvJ9)`&pYw(zRaG@c zI_l;X!`Dj1Rc{hy!MfpYt)uzPnp;KXvIF9|I0aM&iT!g35oj+@GrRu!0ReBmbWP#4 z=Q$3Ji59WFdydM?F}vKcX_8h!Nm2 z2NXUnj6rm5cabx7Y?(B*ABEtVgUzw1lXN)2dI({-Zj{1RXpr87VyqYvRW;dEKxfGE?l~cBBtl|_tCX^QHL<;&n|ll5 zo#BmrscZqsTM3vDv=4$UBDYC_Q^hgz$PY6kbLVUby^~$FPjR1CKynI<^D0QeI*DP7 z7(Wk^x!XLB|H$<^o^ocG?e$?Rhp&75M+;t2pap$wQ8^%Qdgtt7Um}BN(7X4YrVdvl zCt!i<4tp%jPZ4dlt|mR>?W@E~-3*Ltinv^nT(V9XZiMQ_W1`|xsaCgLl6zb%C&QW- z=^1jWT&H^Pc)w^3yekpK~a$g}a* zD_|-(ag(W(d0MINv;1V$nHgz@cNfD`7UcOL;rcnZPNCzlf?eoKbw{=52-86$sWNCe!={NE$YS3Z=mrfKH`h6A$NDC#6YRkF{qtq4}niQ%v*GVruA~?8{ zzUR7TNV`5k@ePv>BMLvKl_cUz}Eq83|*4Tl*69! z0K>*i!gzBDB56v8Gx+a%@V{zp<=N)G&JzIO{wV-}_orwkDkZESDK4id$!KT#kDv;Y zeCzHMT%T}!S0I=3u)Yd_1XVVWl=&a3o2a6awzPueFW5I)S`h5tv60XYUIU0A#f}C5 z!1&X-sg;TAUxM9tJ#rAF zx3X;JX>8|cYxbA2j5t1_Yxwbp7B2QZy0x?`eru4-%LG~(`Jd7K1ODqj3?R|@r@Hu; zEM9lx^b(x(I}_0@Rg@Bl$q2+m`3F<7lL;6u97v4+8`tM*{Sz0S9{L&!go^+vywrc- z;*~szeh9Uo=MnGtf~YRh1MMeHQ(d!!5QOsu;i&$=CCi$E;XU?uA~iPw-!tEr0Ez0ud=)5V#KR6&l_T z*E5nI$710DfCZxe6aDY5|L$6?m;|`I0(HsQ4<1oLzRXjr7#9y68bl)NI$9=oO};Gc zKK0-?5i=WU80Xp+3O^~4$Hh9)j-2X2Md1GS=6bILwa9m51k`# zxmNmUnYgmH^-P~P3@;68(JFu0&?;ZNW5L9cb?J|LaXms}aI6@<5UtOFsdoYly!J9E zh-{!<8dN9UPj=Y4P)*h!l&MkbXBp~yF)qOPIkUK>{iB)uI>n8sVAsHDg>D!V{bors zOiuK}Yl=5e&r)SKQLpS!`UZzsikuS4Hz}An_zss8`wG>9Qz{bQQAC;z&r?{4)Up_2 zJz1b*CE5BAK6dt8+kGiW2|fu6c;nHj(Px(W<~d_ril?hKf=`ua4Z6%pLPf+2G8MjJ zD3nqtm~8qHqL=M35~*;cwCq!HWnH>@w#d3er(RIBL#hV`$#6Ht*hb-Yd?TFaCABT1 ziBg_+QVss;EYHXV?0Q(%grQ2LF(WCMyeEVM-X$s1QY*3RL#%_bVZg!f0ox{@TWZ$zo_``M|u{UQ~Jpi6KHdK0I)vKF z{PHdm?QPa#l>a>9!F zSY7i}%mB#Z3eJ%Qxusm(66*)Sbbw57yi9QJ59XZevvq?CUzPFRQF3jn;uyN1JE`(x z+QOvEcxWXmj2(=@<|Ua*nb%%#7=T-hnV`)#ns9Z3kT{|*mnKMS%+Vg6`qnDKfKX}rZWd`V6rms<;4jzoi zIuJ-@#oR1gb(<6F)~wD|nyo{*KywlXaHfajiIAS#el=pxIIk+dpkY{d;}HyNk-N^2 zf1~M0ooDVncMS$Fa(c)f;9f5w&rj=_afvB8Haw_O=;XAad;4}hQ>nou-Ln)P3$osw zKk*nnLd}L~7@;;3IJHMP?%r6YCS}H1b@KK4OwA2Pb7;OZpM@cyXg4KEf}u>Lu)E=m zj^4Mm>*!hw_^{A{Y(f=Sa=FkOd#u-XP!E$f&TGA?aw@inBoIOn*zt z_H{fo|DMYI=Bpo8W<}2|-6(14e$<53X{wV52NTzW?6L`}X;KC*QZBJ)qmMlpGc6x| z^K}xoP`yE&pg)q=hkR>dF-0Ol%a`N~jM=7dGinBtS{dlreD(Kq&#lj-H1h$f#Z@btt8Le6{rQDv>I z+7-ZyXmIkRNZ4r~8k58YiyK5MB}(EN0hhyGx^;jvQzK<^Kj}w~H&UleqbsI~y-z&U%JtL4d*ADl3r(o_M^F z5I1RC_S9J=EHUd95^R3Rl%ygn$yHpr8DsFYt+IxtL8!y~3jWs%WE-NwP4`~mTM$*{ zin8x5ae>Xn8{(P;W9btFrYx4iGx&%*srQ_^Iz#3JFPm1)qeL6Q$uHj}7Fsf?ZY54!uli~EXZ`rN z0fRo^dxW4HOb-OQPwHxZ%Vlhi#OO`pr%^MjhSslNeJk6k#GKp}arvk}W;)?cMU|w+ zTE19~cnc;m!SZeSgVX%y#boSWeqO7Nb7ce!!S!uYUl;RJD+W8oF*n2INbm%eT<%3j zY8u?lE6>c-N~uw{5=?<9Hgv$rRAn*KQPb z2UtAxt%zDa|Gv4cjpL+aBD2b3Zn8iZG1zU@`V1X%x9^)=W(jP%OfP)=ti7^Q)+Aug z?2VfPohwvNbJAXHv*2CFdX!b)P_sb&FNknj_eKP)?dP??Jp20L^;Zq}Y8ZV8r zve+kHZkDUNIm;=eJur-qwWsCNUnq1=I{-U8Z0r0nF7cKT4uSJfuMpp~UN)A=@!!rs zP`1`7d@Ex%3-X9f-m|qBTm34x#m11PSa3+obg)|`M^To{UG==7n4_xDGb1TwQTWtt zq)8p4OwV^(Y?fV?w6S7vHNXkttc9pwi@6h@9 zYHQRLb+GI9Jq6t+BNq^4K#jkI}PTrVa2 z&cx+#RgWBvjm^NPu6$zhg1sq~OimTs_bm-XXe4<+!ZnZ0Y_SA^oXIZjg>b^EUeRo3 zEyu@`Mm#hYuMWEH(unX(JEmYU`6HRq^K33dZXA4fp;`A8zUo}7!>?OPsuqzVrAu+<2eIp?ZB>GgNyu%4l*%j%5K3Y!amJm}eCNb+u{A$d0 znRT!J*e6W20>fPp))z0QhkerqxE*4XPb2}svtu8fo~-vd*L|bayt4vkl|KTWJmB-k zs%iJVRN_V#W_?Swpqhq=nk07h=+}((Q4b$4wB&)%C9ASjHY~8k$3rQ$6dHW_Wcl~- zp)EE`^K;r2j^ypd05z8l)@zlCsI~be8_Cp%HaNWeUQS`)^@}eAQSJ(`KwbRvTfb+b z4_|PE-#BYmdLWd)*;#jyW<0kGmtr1!ZasEx_p$|w2uj^{=*z|NjwKX7W8 z<@t_cNNO3#W6TVPIJxx4z|(O^HpE z2JtxIhc|ovWr>ywjYatmo$7+cI(nUCIhQ35$vv){NuO+d*-e2DSic^`k-XyaaZvz( zK^_1A{m+Aiz1icV@HpsPz*5hK!uI`0;@(c$5Cl3A&4G^b{{#8UnV>GMFB9^|A-b>o zIYtra09`2hpND8?Gh@?7N7^ZnQ`@0cSRkq$7+ZVoRrghT3pq8sPY)$Fj!L<_b$lz0 z9nuX^1H;^^Ixa^16aP7IKlqWLL|I)`tQ3Zm95Y?CK3$P~bywYzOB*X#jWFA6@P1C) z_riTlOW6L_t?L!&8k`LP)8tuP{`$nSXnm`kR_<>vx3)u+tqf(INb?I`E`A-<`vjEO zCZFWx{)DURjZ=-WNcMqbxv(B1>|jDv315jJZ+N_jjLv1CA}e^#c6O4YDf%E@Z-mdW z>MSTWH9Z3{#>B7ZlnPc4*{rE4{q!2v?>=U$526~-#?zLPsqP%;m~bgDIL+82 zA6z23W}qf6SQ{%IPL`BfrnJsMQ4eejS5l#NA5F`V-I}@{6MwL{OuJ~Uz;yO2Kk&^Q zWY{F*UVtubODj@in2JRZy=?RwRPkv|;0Tj0qeOXT70T=%7fbE49gEO(+8XC{z9b*L z6_2Piv}wN7SD%(y^dX#mdA~vD>qolOnjscfLhD&tVMdHmq8jhouL@5fOMQUqNi2Pn z9i?*f^P-|=M~IG3Q_UtKOxe9)p>MrIs##9C<;xN&cuDgqw^C(_dB^a-y!b3<#$6l; z6Z%fY>9~SgpGHSqT8Vdr*B}Y~v(*k-UY$1AhwQCXh9jG}p?ZwL>c%?g@kY(qxY$~9 zX)DBXNlhyL6`{+{#ilFGZ!GpeRWPIhOi#A6cVC?`1QYp$bZY4Q)#Z9S6+TvrY}Mxo ztnB#nI38dK7xoL%VrR2y1I*@vc=&x&%8@vYT|cJO`UxqQe(Gz-_iOGUi$ktxZ|%Lw zG!aLV-xe4QVw(DFC#+{y6qCpskXw6`Qf5~s5#yE}K$i`E}iNY8QYQB;%QD@g+R9^9i1%G9o+CcR(5CzoIx$X#A+ z1liBx9X~2&?GmNgOr)#+O(4-LF>teGyoH+v&cMpIlKQyYnz<=3W#hD%_G(l-r(c0Z z)~Xy~Ao{}xP2>s$vS*{}K%)~c;m@Vcey3~-wlWB@kg475I%ayT^2N?LLuZAv;I;9M zZGDXB{wGRWr5vA=9Mg(X4mE=7t?LfbI=Dr9sKV*z5SV4ff(;_$s>-qM68aXFLu|Pd ziVdtnVTV*{FO!PxhtZ1@t?bLDQ%D=xYRa#^&T7)@s^fLZtQtC(03irx-jUMH5p~;n z21ea~AvTB3dcqoXMED)m|Pyz?vlTqR@$Rq)JPXy?ntI zu57z3eto_y?Ap+qQ?Zr%g6mw4tv+|T%&`|nFebktDnqb|Zz+TkWGBm_P~JNpP@+lMK?w-I>pyOnzO6-{|$6C1-X z-*U0}F*Rnic42Gx-k#ffSb-^Lu3($E^+}g@S#_63oGu#s1OV&(GAcKu$9koz`l3yV zw&Nl{aFiMmYb3_ENDc}6s3&}JZc^{{7;_8n2!i{lP8aejue*&g|BR(TCOk&Xns1U~ z*`+-on4L?4B` z%!4OTA;BZ;bmRSaBIx85OFbImqRxP%pX#7<2C-Er)tO@t$RK4-#?wfVc1 zxV4G_Ox0E30^RGIt9*LQSpPF<@OsT}0p z>qm;LqBVl%4^bTL^psge7vBMw*lKJ%N&!?3ps*EccXDf&DJ=rr(lt^Rs5hCRj>ZuM6PZX5g1n z0+pwq0Nt>~8=s3l7rv6F#__4o7wW>7d?VrYE#(ed>HLfkErr!>f~I2)ZeGW4J?66d zl9W1C1H71?GEEc4L7ivJz}ZR*ub2o?(h6U#K>9}RNpxOolWi_s-RCCcw-~Ns%cGre zTFcpHhNS-YCEPu7?{~NNtWMrpGL&o{mWH6~(<6vB35uiBjo>xy?b~ywQ1zgJe_to{)t4i#C}AnaGDc9e=0G zAViw1I25tf&p9gFN)&SP7^NPsIfy$(_0Qp~Yg;jkjx?U8zr^Cg41RswqyZ}J$_2;;<_w=}TSxUR)tKDQODOfsY&)eF)=sZN#8=erWXh3o^ z--BD^pB`s>R)3aV zc4yf5`J0HH;F4^}u*&BHu1)00-~~=o78O0ZC1rMa(ysW6XSuN+vNX@Y>?z*MTo4GG+y(c7Zg2NA^&3|jwcR2TD7Q*Lgi)T+3 zt$&)tG*9%4WYFDAM2voW?vV>#La~PfFb8R=S#pQPZa2hJq8SPNHTef1gFjeYx07sV zpIG}+9;nR3_@;nrcoD8t<@3cuzsraogW{LhUGHe+; zBp}m;nm*w*bwi7azL1WRM~m6MDF4vA6xUahK=2g;2%C8VHInjX~I{~zNI zAg9K*whktb+S@^%o7R}Y_QS2LH#HTyKkQh@`^66eRYS@)dln`fXY ziBF*GjQ_Yc^RTjKWqITVbmh`?pa>=d#>x9yQ+_Q}EO!*N!ViR?yO2N63i8G_X69D5 zKW8-F9*uv$Mrg8A23vmu{QK%}T31Ux4Z$086?BExfbpLp82{*(|CuShj}y8!ppTm; zJOB)o9{}LTKMh*CE+2+b{XS~CdJ#QWg>;|L{h(SB7yPW$C|v5f@9j3)v{8|UR0QLJ zv%(>8Vu2Ni7Pc}lL|N%fVqVnMIljOkaYuMDG)K zqFkvSh6{M(O7S%HBhDReQ6hccF}lWi;}bIxCk^EUyLkHjLsFaL%>mVG9lP zpBMOKt_&HCnKNR^3pQnF#b_cb!a~QAsGe(U1nbQM6Gv6xW>WT4V&qCj_ejyK&1hz- z7pG|HIClIyhppwca|P;JpC`y;jwD8j3}7q4YPu-fnyQDVoRY2#V|bDwNTNUr~oF$OQ~5DCwwfTI=<;!_U`iuu0r$&d0dd2S?NuuZPvc zt&F~kNkD*sTYg!LhC{hSazkqqwd!VioK04Mwhdv`jB1;BiUUogp$G~+8Ey&7^AT`8B1NKevv4fqpEhRxl8(CIIw&> zj;^^#MPJ`+$+J5&sN^vISRv4&w+?o~W#Y~@x`LU%-Drk%CbP@)a*HjegcnaYOEH9X zp!BKdWiP2?jibren094OXrGWXk$DG~iBn%^{@UzaRy6h#xpKr zpi#^gG+SNv0bmf^quU$jKre3f3BPt0cfaOVPu5aTqzZQpMChD+&O}bjd#J{i6db}a zto79k4BT&=jUe4^QE}cA7B45cd?M*-j3B#t-BXV>i^0>y05U@&^!ZT^Lh~dI7>B_| zi&U^SH%}H+F>G##=rM+wU6_4NctV_Y;0T~PqEc_L>At3$`(S3#lZEj8)?rsT5{oG# z-+nlv2UXM-6X9()5@vvSbS1Bb@fE{yot@4-|CpX3l>K{M2b)nDvh zXT!BV)yis0foa@dCHXiJhVtA<$h-XcA#1>fy!;@f&T=NJbwC>mniUDV6$^Xy$Z&@2ZM^j zGNFx)MHqw2OEF)dFp$YtW3yOvbvpJBAL;Bdh zs%4IdI{b3$$Palo(J~f=O58fR@x}_TP{saKY?I74=pOS39dQPFTA69m=j+afac$=Ux;}Ca!V}3*hT(&%u&z ziC^Kjp>@YpB-_G|1)gLvmHq67U_m(ut7iau3QIjRo*HhkMdmH1{Y1I(!gD8J*`PkXkw@)H zZ%r4khTl1J(h%!L!FRwoGyE!drUz#y3 zKuU#fkxmLI&=-a%5wbOBc+%^@^Yb_A^l?VvrzpoDkXIF7qHOB+#T?Iv4Whh2qR}$R zC{oXq@b;!-ZX?EnMK!Mk%D>K~s<=E^!t+=`-dcp1UpqWmYi|?e$Bx|gg$ekIP}bK* zyy3+nBbG9MofxzsZHrvO!u$SUG%j;bqLhwsWjba9?t_kFn6hH)c#4YHlnwYRT;s-T z3x;7C@s<`T1Qj^)XAxh<^Pik*G%;NrLrg1Le)AY)_fvqKotW<31DbKpVlygtTOXi1 zCYPPqykk<1-2}Tlpv)|Nrg+kEN3dqAhP*s;NMWyeuoPqe(K~P{Uu0LZ-1AN#gKXFp zkCH`TyKTn2Bsv{FKmK&sols--a-&cuCkbP_3s?lEhZ9ldI?AY*R6^tXDUXqrGEBAhVZ$`^I{ z17kl8y9cJk-uKd9(irnSSMC!8BoHH;K54lS$*#DUBy>e;4)p1ejx#NZrH0QxbX^KA zZ}R6&Rbm)=Yu|MOMePJ0pp<06zzHG#86-{C(gmYJ{;LX9SA+U7N}7zS4~GAvk0QBJ z7mV`nLg?|-D98}h=JLoe)({MrauQTg{61>>cuw?R6y~ED(PTtDFkJEyPzCiH_Ma)v zAA$Yq&jy5{{`P-he$I~m>+!Dzje&5qY@nj+fBE`*V)PFrvpyIu8V0D%=~ra3zCIY% zKgp2(uH^nY5{mu3&H{jHL_k5n7tq+{uW+V+7WvPB=pUYML7o|3V*Y=ie~pDcLO=T+ zjCN3DPZ=mrPe9L{2-NHHZ!qQfzcVJs7=U5^vlf}}@LvZ;AH%Cb{VV@#E&q;>J__gO zj$#6B6l#3(|Bd}QNBRfu#1M=U?>~n~ADJTlGC-QFYXnAs`8Ve8xlxcgXm0e;)`c?$ z!=;Ll_#>iUo8}&Q`MD4q5R8;t=}*|-t#XeLKPH8LZIgSP%0bmXSpIIB`<>+1hPlTi ztH%FL0xJFgCBgi@4M0Dj2D)SfJup0SdaFNB|8&It0D{`-9_4D~IT-FUzyAaCYZu+W zj`4qN#$P+=9!D=>`+FSU`{@Y&*^EDPUIS{eL%X#9-4xV9hY$V8*H2?2Q;@NP)9=RL z`{oG$<^A3;mmKxo^vLB8(`HjJ5(rSQ+@lQKemC`V|HG8p>=Ema#s1nF_js|GUcbZR z9Rq$@!4HC8`{W)IaJ~4Q;Cn9|2K1>6n`H3#Z&!*<{v2t!~&9nlJ9K5h@mBQzn3Qe E58P$Ood5s; From 8c4be12f3ba4dc1608ffd85617c2f721d68e4865 Mon Sep 17 00:00:00 2001 From: zhangchengwei Date: Sat, 27 Oct 2018 15:17:45 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0hiredis=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/hiredis-0.14.0.zip | Bin 93219 -> 93223 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/vendor/hiredis-0.14.0.zip b/vendor/hiredis-0.14.0.zip index 06b0892a4cb20f7fde7f433b696a81e7a18af346..6f97da48a2cbcbd716e2557289302020aefaf2b1 100644 GIT binary patch delta 5570 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 U_4hj2{=B`!XlM$CfA95w0QMPNqyPW_ From e440098f659f7ada2c5070026b73912fd5af4d3d Mon Sep 17 00:00:00 2001 From: zhangchengwei Date: Wed, 31 Oct 2018 09:43:41 +0800 Subject: [PATCH 3/3] =?UTF-8?q?curl=E6=93=8D=E4=BD=9C=E5=8A=A0=E5=85=A5?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cache/src/tango_cache_client.cpp | 10 +-- cache/src/tango_cache_client_in.h | 1 - cache/src/tango_cache_transfer.cpp | 75 +++++++---------------- cache/test/cache_evbase_test_threads.cpp | 5 -- cache/test/lib/libhiredis.a | Bin 460438 -> 460470 bytes cache/test/tango_cache_test.c | 2 +- 6 files changed, 27 insertions(+), 66 deletions(-) diff --git a/cache/src/tango_cache_client.cpp b/cache/src/tango_cache_client.cpp index c6fa89d..54dd8b7 100644 --- a/cache/src/tango_cache_client.cpp +++ b/cache/src/tango_cache_client.cpp @@ -261,12 +261,12 @@ int tango_cache_update_frag_data(struct tango_cache_ctx *ctx, const char *data, { if(ctx->fail_state) { - return -1; + return 0; //TODO: 暂时忽略返回值!! } if(evbuffer_add(ctx->put.evbuf, data, size)) { tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); - return -1; + return 0; } ctx->instance->statistic.memory_used += size; if(evbuffer_get_length(ctx->put.evbuf) >= ctx->instance->upload_block_size) @@ -282,7 +282,7 @@ int tango_cache_update_frag_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COP if(ctx->fail_state) { - return -1; + return 0;//TODO: 暂时忽略返回值!! } size = evbuffer_get_length(evbuf); @@ -291,7 +291,7 @@ int tango_cache_update_frag_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COP if(evbuffer_add_buffer(ctx->put.evbuf, evbuf)) { tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); - return -1; + return 0; } } else @@ -299,7 +299,7 @@ int tango_cache_update_frag_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COP if(evbuffer_add_buffer_reference(ctx->put.evbuf, evbuf)) { tango_cache_set_fail_state(ctx, CACHE_OUTOF_MEMORY); - return -1; + return 0; } } ctx->instance->statistic.memory_used += size; diff --git a/cache/src/tango_cache_client_in.h b/cache/src/tango_cache_client_in.h index a9b7688..123a84d 100644 --- a/cache/src/tango_cache_client_in.h +++ b/cache/src/tango_cache_client_in.h @@ -158,7 +158,6 @@ void easy_string_destroy(struct easy_string *estr); void tango_cache_ctx_destroy(struct tango_cache_ctx *ctx, bool callback=true); void tango_cache_set_fail_state(struct tango_cache_ctx *ctx, enum CACHE_ERR_CODE error_code); -const char *tango_cache_errcode2str(enum CACHE_ERR_CODE err_code); const char *tango_cache_get_errstring(const struct tango_cache_ctx *ctx); struct tango_cache_ctx *tango_cache_update_prepare(struct tango_cache_instance *instance, struct future* f, struct tango_cache_meta_put *meta); diff --git a/cache/src/tango_cache_transfer.cpp b/cache/src/tango_cache_transfer.cpp index 20dd2f6..c404e77 100644 --- a/cache/src/tango_cache_transfer.cpp +++ b/cache/src/tango_cache_transfer.cpp @@ -13,6 +13,19 @@ #include "tango_cache_xml.h" #include "tango_cache_tools.h" +static inline void curl_set_common_options(CURL *curl, long transfer_timeout, char *errorbuf) +{ + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorbuf); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, transfer_timeout); //测试发现多链接有某链接接收卡住的情况 + //ctx->error="Operation too slow. Less than 1024 bytes/sec transferred the last 3 seconds" + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_TIME, 2L); + curl_easy_setopt(curl, CURLOPT_LOW_SPEED_LIMIT, 100L); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); +} + //response body很短或不关心时 size_t curl_response_any_cb(void *ptr, size_t size, size_t count, void *userp) { @@ -119,23 +132,16 @@ static int http_put_bodypart_request_evbuf(struct tango_cache_ctx *ctx, bool ful curl_easy_setopt(ctx->curl, CURLOPT_HEADERDATA, ctx); } curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url); - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); - curl_easy_setopt(ctx->curl, CURLOPT_TIMEOUT, ctx->instance->transfer_timeout); //测试发现有某链接接收卡住的情况 curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L); curl_easy_setopt(ctx->curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(ctx->curl, CURLOPT_INFILESIZE, ctx->put.upload_length); curl_easy_setopt(ctx->curl, CURLOPT_READFUNCTION, curl_put_multipart_send_cb); curl_easy_setopt(ctx->curl, CURLOPT_READDATA, ctx); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl); assert(rc==CURLM_OK); @@ -183,17 +189,11 @@ int curl_get_minio_uploadID(struct tango_cache_ctx *ctx) curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDSIZE, 0); //默认使用回调函数调用fread,测试发现关闭Expect时会导致卡在curl_multi_socket_action curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url); - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL,1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_body_save_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl); assert(rc==CURLM_OK); @@ -217,14 +217,10 @@ int cache_delete_minio_object(struct tango_cache_ctx *ctx, bool call_back) snprintf(minio_url, 256, "http://%s/%s/%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key); curl_easy_setopt(ctx->curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url); - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl); assert(rc==CURLM_OK); @@ -245,14 +241,10 @@ bool cache_cancel_upload_minio(struct tango_cache_ctx *ctx) snprintf(minio_url, 256, "http://%s/%s/%s?uploadId=%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key, ctx->put.uploadID); curl_easy_setopt(ctx->curl, CURLOPT_CUSTOMREQUEST, "DELETE"); curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url); - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl); assert(rc==CURLM_OK); @@ -275,17 +267,13 @@ bool cache_kick_combine_minio(struct tango_cache_ctx *ctx) snprintf(minio_url, 256, "http://%s/%s/%s?uploadId=%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key, ctx->put.uploadID); curl_easy_setopt(ctx->curl, CURLOPT_POST, 1L); curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url); - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL,1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDSIZE, len); //填充Content-Length curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDS, ctx->put.combine_xml); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); if(ctx->headers != NULL) { @@ -508,18 +496,11 @@ int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEM snprintf(minio_url, 256, "http://%s/%s/%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key); curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url); - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); - curl_easy_setopt(ctx->curl, CURLOPT_TIMEOUT, ctx->instance->transfer_timeout); //测试发现有某链接接收卡住的情况 curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); if(way == PUT_MEM_COPY) { @@ -632,17 +613,11 @@ int tango_cache_multi_delete_start(struct tango_cache_ctx *ctx, bool callback) curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDSIZE, ctx->response.size); //填充Content-Length,在CURLOPT_COPYPOSTFIELDS之前设置 curl_easy_setopt(ctx->curl, CURLOPT_COPYPOSTFIELDS, ctx->response.buff); curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url); - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_body_save_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl); assert(rc==CURLM_OK); @@ -878,20 +853,12 @@ int tango_cache_fetch_start(struct tango_cache_ctx *ctx) { curl_easy_setopt(ctx->curl, CURLOPT_NOBODY, 1L); } - curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache"); - curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL,1L); curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_get_response_body_cb); curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error); curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx); - curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L); - curl_easy_setopt(ctx->curl, CURLOPT_TIMEOUT, ctx->instance->transfer_timeout); //测试发现有某链接接收卡住的情况 curl_easy_setopt(ctx->curl, CURLOPT_HEADERFUNCTION, curl_get_response_header_cb); curl_easy_setopt(ctx->curl, CURLOPT_HEADERDATA, ctx); - //ctx->error="Operation too slow. Less than 1024 bytes/sec transferred the last 3 seconds" - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L); - curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L); + curl_set_common_options(ctx->curl, ctx->instance->transfer_timeout, ctx->error); rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl); assert(rc==CURLM_OK); diff --git a/cache/test/cache_evbase_test_threads.cpp b/cache/test/cache_evbase_test_threads.cpp index 9d3827b..b792bea 100644 --- a/cache/test/cache_evbase_test_threads.cpp +++ b/cache/test/cache_evbase_test_threads.cpp @@ -193,7 +193,6 @@ void* thread_upload_download(void *arg) { sprintf(filename_out, "file_index_%d_%d.bin", thread_data->thread_id, i); pdata->future = future_create(get_future_success, get_future_failed, pdata); - promise_set_ctx(future_to_promise(pdata->future), NULL, NULL); pdata->fp = fopen(filename_out, "w"); cache_evbase_fetch_object(instance_asyn, pdata->future, &getmeta); @@ -201,7 +200,6 @@ void* thread_upload_download(void *arg) else if(!strcasecmp(p, "DEL")) { pdata->future = future_create(del_future_success, del_future_failed, pdata); - promise_set_ctx(future_to_promise(pdata->future), NULL, NULL); sprintf(pdata->filename, "%s", filename_in); cache_evbase_delete_object(instance_asyn, pdata->future, filename_in); } @@ -210,7 +208,6 @@ void* thread_upload_download(void *arg) size_t filelen; p = get_file_content(filename_in, &filelen); pdata->future = future_create(put_future_success, put_future_failed, pdata); - promise_set_ctx(future_to_promise(pdata->future), NULL, NULL); if(cache_evbase_upload_once_data(instance_asyn, pdata->future, PUT_MEM_FREE, p, filelen, &putmeta, pdata->filename, 256)) { @@ -223,7 +220,6 @@ void* thread_upload_download(void *arg) { size_t readlen; pdata->future = future_create(put_future_success, put_future_failed, pdata); - promise_set_ctx(future_to_promise(pdata->future), NULL, NULL); struct evbuffer *evbuf = evbuffer_new(); char buffer[1024]; @@ -249,7 +245,6 @@ void* thread_upload_download(void *arg) else { pdata->future = future_create(put_future_success, put_future_failed, pdata); - promise_set_ctx(future_to_promise(pdata->future), NULL, NULL); ctx = cache_evbase_update_start(instance_asyn, pdata->future, &putmeta); if(ctx==NULL) diff --git a/cache/test/lib/libhiredis.a b/cache/test/lib/libhiredis.a index 670ea58f661f76385172a6664ff604f269442b2f..e0c95b67ef7cb022137a0ca0c3f41ecf0242403a 100644 GIT binary patch delta 27538 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 diff --git a/cache/test/tango_cache_test.c b/cache/test/tango_cache_test.c index 560673c..19c6b19 100644 --- a/cache/test/tango_cache_test.c +++ b/cache/test/tango_cache_test.c @@ -312,7 +312,7 @@ static void dummy_accept_callback(evutil_socket_t fd, short events, void *arg) ctx = tango_cache_update_start(tango_instance, pdata->future, &putmeta); if(ctx==NULL) { - put_future_failed(FUTURE_ERROR_CANCEL, "NULL", pdata); + put_future_failed(FUTURE_ERROR_CANCEL, "tango_cache_update_start_NULL", pdata); continue; } tango_cache_get_object_path(ctx, pdata->filename, 256);