cyga / www_fdw

fdw extension for postgres
http://wiki.postgresql.org/wiki/WWW_FDW
123 stars 21 forks source link

Query timeout #17

Open prdn opened 9 years ago

prdn commented 9 years ago

Hi,

how can I pass a timeout value to www_fdw ?

Thanks

cyga commented 9 years ago

I can be achieved using one more option. Patch has to be smth like:

diff --git a/sql/www_fdw.sql b/sql/www_fdw.sql
index 7bb6a88..667eccb 100755
--- a/sql/www_fdw.sql
+++ b/sql/www_fdw.sql
@@ -13,6 +13,7 @@ CREATE TYPE WWWFdwOptions AS (
        method_delete                                           text,
        method_update                                           text,
        request_user_agent                                      text,
+       request_timeout                                         text,
        request_serialize_callback                      text,
        request_serialize_type                          text,
        request_serialize_human_readable        text,
diff --git a/src/www_fdw.c b/src/www_fdw.c
index ad095d1..02dc157 100755
--- a/src/www_fdw.c
+++ b/src/www_fdw.c
@@ -66,6 +66,7 @@ static struct WWW_fdw_option valid_options[] =
        { "method_update",      ForeignServerRelationId },

        { "request_user_agent", ForeignServerRelationId },
+       { "request_timeout",    ForeignServerRelationId },
        { "request_serialize_callback", ForeignServerRelationId },
        { "request_serialize_type",     ForeignServerRelationId },
        { "request_serialize_human_readable",   ForeignServerRelationId },
@@ -97,6 +98,7 @@ typedef struct        WWW_fdw_options
        char*   method_delete;
        char*   method_update;
        char*   request_user_agent;
+       char*   request_timeout;
        char*   request_serialize_callback;
        char*   request_serialize_type;
        char*   request_serialize_human_readable;
@@ -214,6 +216,7 @@ www_fdw_validator(PG_FUNCTION_ARGS)
        char            *method_delete  = NULL;
        char            *method_update  = NULL;
        char            *request_user_agent= NULL;
+       char            *request_timeout= NULL;
        char            *request_serialize_callback     = NULL;
        char            *request_serialize_type = NULL;
        char            *request_serialize_human_readable       = NULL;
@@ -271,6 +274,7 @@ www_fdw_validator(PG_FUNCTION_ARGS)
                if(parse_parameter("method_delete", &method_delete, def)) continue;
                if(parse_parameter("method_update", &method_update, def)) continue;
                if(parse_parameter("request_user_agent", &request_user_agent, def)) continue;
+               if(parse_parameter("request_timeout", &request_timeout, def)) continue;
                if(parse_parameter("request_serialize_callback", &request_serialize_callback, def)) continue;
                if(parse_parameter("request_serialize_type", &request_serialize_type, def)) continue;
                if(parse_parameter("request_serialize_human_readable", &request_serialize_human_readable, def))
@@ -1368,6 +1372,7 @@ get_www_fdw_options(WWW_fdw_options *opts, Oid *opts_type, Datum *opts_value)
                opts->method_update,

                opts->request_user_agent,
+               opts->request_timeout,
                opts->request_serialize_callback,
                opts->request_serialize_type,
                opts->request_serialize_human_readable,
@@ -1749,7 +1754,9 @@ www_begin(ForeignScanState *node, int eflags)
        curl = curl_easy_init();
        curl_easy_setopt(curl, CURLOPT_URL, url.data);
        curl_easy_setopt(curl, CURLOPT_USERAGENT, opts->request_user_agent);
+       curl_easy_setopt(curl, CURLOPT_TIMEOUT, opts->request_timeout);
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_error_buffer);
+       curl_easy_setopt(curl, CURLOPT_TIMEOUT, opts->timeout);
        if(post.post || 0 == strcmp(opts->method_select, "POST"))
        {
                curl_easy_setopt(curl, CURLOPT_POST, 1);
@@ -2158,6 +2165,7 @@ get_options(Oid foreigntableid, WWW_fdw_options *opts)
        opts->method_delete     = NULL;
        opts->method_update     = NULL;
        opts->request_user_agent        = NULL;
+       opts->request_timeout       = NULL;
        opts->request_serialize_callback        = NULL;
        opts->request_serialize_type    = NULL;
        opts->request_serialize_human_readable  = NULL;
@@ -2206,6 +2214,9 @@ get_options(Oid foreigntableid, WWW_fdw_options *opts)
                if (strcmp(def->defname, "request_user_agent") == 0)
                        opts->request_user_agent        = defGetString(def);

+               if (strcmp(def->defname, "request_timeout") == 0)
+                       opts->request_timeout   = defGetString(def);
+
                if (strcmp(def->defname, "request_serialize_callback") == 0)
                        opts->request_serialize_callback        = defGetString(def);

@@ -2252,6 +2263,8 @@ get_options(Oid foreigntableid, WWW_fdw_options *opts)
        if (!opts->method_update) opts->method_update   = "POST";

        if (!opts->request_user_agent) opts->request_user_agent = "www_fdw postgres extension";
+       // default timeout is 0 (zero) which means it never times out during transfer.
+       if (!opts->request_timeout) opts->request_timeout               = 0;

        if (!opts->request_serialize_type) opts->request_serialize_type = "log";
        if (!opts->request_serialize_human_readable) opts->request_serialize_human_readable     = "0";

Unfortunately I can't test it myself, but you can check it. Let me know if you give it a try.