{"action":"created","comment":{"url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments/25157997","id":25157997,"diff_hunk":"@@ -0,0 +1,412 @@\n+/*##############################################################################\n+\n+    HPCC SYSTEMS software Copyright (C) 2015 HPCC Systems.\n+\n+    Licensed under the Apache License, Version 2.0 (the \"License\");\n+    you may not use this file except in compliance with the License.\n+    You may obtain a copy of the License at\n+\n+       http://www.apache.org/licenses/LICENSE-2.0\n+\n+    Unless required by applicable law or agreed to in writing, software\n+    distributed under the License is distributed on an \"AS IS\" BASIS,\n+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+    See the License for the specific language governing permissions and\n+    limitations under the License.\n+############################################################################## */\n+\n+#include \"platform.h\"\n+#include \"jthread.hpp\"\n+#include \"jhash.hpp\"\n+#include \"eclrtl.hpp\"\n+#include \"jstring.hpp\"\n+#include \"redissync.hpp\"\n+\n+namespace RedisPlugin {\n+static __thread SyncConnection * cachedConnection;\n+static __thread ThreadTermFunc threadHookChain;\n+\n+//The following class is here to ensure destruction of the cachedConnection within the main thread\n+//as this is not handled by the thread hook mechanism.\n+static class mainThreadCachedConnection\n+{\n+public :\n+    mainThreadCachedConnection() { }\n+    ~mainThreadCachedConnection()\n+    {\n+        if (cachedConnection)\n+            cachedConnection->Release();\n+    }\n+} mainThread;\n+\n+static void releaseContext()\n+{\n+    if (cachedConnection)\n+        cachedConnection->Release();\n+    if (threadHookChain)\n+    {\n+        (*threadHookChain)();\n+        threadHookChain = NULL;\n+    }\n+}\n+\n+SyncConnection::SyncConnection(ICodeContext * ctx, const char * _options, unsigned __int64 _database, const char * pswd, unsigned __int64 _timeout)\n+  : Connection(ctx, _options, pswd, _timeout)\n+{\n+    connect(ctx, _database, pswd);\n+}\n+SyncConnection::SyncConnection(ICodeContext * ctx, RedisServer * _server, unsigned __int64 _database, const char * pswd)\n+  : Connection(ctx, _server)\n+{\n+    connect(ctx, _database, pswd);\n+}\n+void SyncConnection::connect(ICodeContext * ctx, unsigned __int64 _database, const char * pswd)\n+{\n+    struct timeval to = { timeout/1000000, timeout%1000000 };\n+    context = redisConnectWithTimeout(server->getIp(), server->getPort(), to);\n+    assertConnection();\n+    authenticate(ctx, pswd);\n+    selectDB(ctx, _database);\n+    init(ctx);\n+}\n+void SyncConnection::authenticate(ICodeContext * ctx, const char * pswd)\n+{\n+    if (strlen(pswd) > 0)\n+    {\n+        OwnedReply reply = Reply::createReply(redisCommand(context, \"AUTH %b\", pswd, strlen(pswd)));\n+        assertOnError(reply->query(), \"server authentication failed\");\n+    }\n+}\n+SyncConnection * SyncConnection::createConnection(ICodeContext * ctx, const char * options, unsigned __int64 _database, const char * pswd, unsigned __int64 _timeout)\n+{\n+    if (!cachedConnection)\n+    {\n+        cachedConnection = new SyncConnection(ctx, options, _database, pswd, _timeout);\n+        threadHookChain = addThreadTermFunc(releaseContext);\n+        return LINK(cachedConnection);\n+    }\n+\n+    unsigned optionsPswdHash = hashc((const unsigned char*)options, strlen(options), hashc((const unsigned char*)pswd, strlen(pswd), 0));\n+    if (cachedConnection->isSameConnection(ctx, optionsPswdHash))\n+    {\n+        //MORE: need to check that the connection has not expired (think hiredis REDIS_KEEPALIVE_INTERVAL is defaulted to 15s).\n+        //At present updateTimeout calls assertConnection.\n+        cachedConnection->updateTimeout(_timeout);\n+        cachedConnection->selectDB(ctx, _database);\n+        return LINK(cachedConnection);\n+    }\n+\n+    cachedConnection->Release();\n+    cachedConnection = new SyncConnection(ctx, options, _database, pswd, _timeout);\n+    return LINK(cachedConnection);\n+}\n+void SyncConnection::selectDB(ICodeContext * ctx, unsigned __int64 _database)\n+{\n+    if (database == _database)\n+        return;\n+    database = _database;\n+    VStringBuffer cmd(\"SELECT %\" I64F \"u\", database);\n+    OwnedReply reply = Reply::createReply(redisCommand(context, cmd.str()));\n+    assertOnError(reply->query(), \"'SELECT' request failed\");\n+}\n+void SyncConnection::updateTimeout(unsigned __int64 _timeout)\n+{\n+    if (timeout == _timeout)\n+        return;\n+    assertConnection();\n+    timeout = _timeout;\n+    struct timeval to = { timeout/1000000, timeout%1000000 };\n+    if (redisSetTimeout(context, to) != REDIS_OK)\n+    {\n+        if (context->err)\n+        {\n+            VStringBuffer msg(\"RedisPlugin: failed to set timeout - %s\", context->errstr);\n+            rtlFail(0, msg.str());\n+        }\n+        else\n+            rtlFail(0, \"RedisPlugin: failed to set timeout - no message available\");\n+    }\n+}\n+void SyncConnection::logServerStats(ICodeContext * ctx)\n+{\n+    OwnedReply reply = Reply::createReply(redisCommand(context, \"INFO\"));\n+    assertOnError(reply->query(), \"'INFO' request failed\");\n+    StringBuffer stats(\"Redis Plugin : Server stats - \");\n+    stats.newline().append(reply->query()->str).newline();\n+    ctx->logString(stats.str());\n+}\n+void SyncConnection::assertOnError(const redisReply * reply, const char * _msg)\n+{\n+    if (!reply)\n+    {\n+        //There should always be a context error if no reply error\n+        assertConnection();\n+        VStringBuffer msg(\"Redis Plugin: %s - %s\", _msg, \"neither 'reply' nor connection error available\");\n+        rtlFail(0, msg.str());\n+    }\n+    else if (reply->type == REDIS_REPLY_ERROR)\n+    {\n+        if (strncmp(reply->str, \"NOAUTH\", 6) == 0)\n+        {\n+            VStringBuffer msg(\"Redis Plugin: server authentication failed - %s\", reply->str);\n+            rtlFail(0, msg.str());\n+        }\n+        else\n+        {\n+            VStringBuffer msg(\"Redis Plugin: %s - %s\", _msg, reply->str);\n+            rtlFail(0, msg.str());\n+        }\n+    }\n+}\n+void SyncConnection::assertConnection()\n+{\n+    if (!context)\n+        rtlFail(0, \"Redis Plugin: 'redisConnect' failed - no error available.\");\n+    else if (context->err)\n+    {\n+        VStringBuffer msg(\"Redis Plugin: Connection failed - %s for %s:%u\", context->errstr, ip(), port());\n+        rtlFail(0, msg.str());\n+    }\n+}\n+\n+void SyncConnection::clear(ICodeContext * ctx)\n+{\n+    //NOTE: flush is the actual cache flush/clear/delete and not an io buffer flush.\n+    OwnedReply reply = Reply::createReply(redisCommand(context, \"FLUSHDB\"));//NOTE: FLUSHDB deletes current database where as FLUSHALL deletes all dbs.\n+    //NOTE: documented as never failing, but in case\n+    assertOnError(reply->query(), \"'FlushDB' request failed\");\n+}\n+void SyncConnection::del(ICodeContext * ctx, const char * key)\n+{\n+    OwnedReply reply = Reply::createReply(redisCommand(context, \"DEL %b\", key, strlen(key)));\n+    assertOnError(reply->query(), \"'Del' request failed\");\n+}\n+void SyncConnection::persist(ICodeContext * ctx, const char * key)\n+{\n+    OwnedReply reply = Reply::createReply(redisCommand(context, \"PERSIST %b\", key, strlen(key)));\n+    assertOnError(reply->query(), \"'Persist' request failed\");\n+}\n+void SyncConnection::expire(ICodeContext * ctx, const char * key, unsigned _expire)\n+{\n+    OwnedReply reply = Reply::createReply(redisCommand(context, \"DEL %b %u\", key, strlen(key), _expire));\n+    assertOnError(reply->query(), \"'Expire' request failed\");\n+}\n+bool SyncConnection::exists(ICodeContext * ctx, const char * key)\n+{\n+    OwnedReply reply = Reply::createReply(redisCommand(context, \"EXISTS %b\", key, strlen(key)));\n+    assertOnError(reply->query(), \"'Exists' request failed\");\n+    return (reply->query()->integer != 0);\n+}\n+unsigned __int64 SyncConnection::dbSize(ICodeContext * ctx)\n+{\n+    OwnedReply reply = Reply::createReply(redisCommand(context, \"DBSIZE\"));\n+    assertOnError(reply->query(), \"'DBSIZE' request failed\");\n+    return reply->query()->integer;\n+}\n+//-------------------------------------------SET-----------------------------------------\n+//--OUTER--\n+template<class type> void SyncRSet(ICodeContext * ctx, const char * _options, const char * key, type value, unsigned __int64 database, unsigned expire, const char * pswd, unsigned __int64 _timeout)\n+{\n+    Owned<SyncConnection> master = SyncConnection::createConnection(ctx, _options, database, pswd, _timeout);\n+    master->set(ctx, key, value, expire);\n+}\n+//Set pointer types\n+template<class type> void SyncRSet(ICodeContext * ctx, const char * _options, const char * key, size32_t valueLength, const type * value, unsigned __int64 database, unsigned expire, const char * pswd, unsigned __int64 _timeout)\n+{\n+    Owned<SyncConnection> master = SyncConnection::createConnection(ctx, _options, database, pswd, _timeout);\n+    master->set(ctx, key, valueLength, value, expire);\n+}\n+//--INNER--\n+template<class type> void SyncConnection::set(ICodeContext * ctx, const char * key, type value, unsigned expire)\n+{\n+    const char * _value = reinterpret_cast<const char *>(&value);//Do this even for char * to prevent compiler complaining\n+    const char * msg = setFailMsg;\n+\n+    StringBuffer cmd(\"SET %b %b\");\n+    appendExpire(cmd, expire);\n+\n+    OwnedReply reply = Reply::createReply(redisCommand(context, cmd.str(), key, strlen(key), _value, sizeof(type)));\n+    assertOnError(reply->query(), msg);\n+}\n+template<class type> void SyncConnection::set(ICodeContext * ctx, const char * key, size32_t valueLength, const type * value, unsigned expire)\n+{\n+    const char * _value = reinterpret_cast<const char *>(value);//Do this even for char * to prevent compiler complaining\n+    const char * msg = setFailMsg;\n+\n+    StringBuffer cmd(\"SET %b %b\");\n+    appendExpire(cmd, expire);\n+    OwnedReply reply = Reply::createReply(redisCommand(context, cmd.str(), key, strlen(key), _value, (size_t)valueLength));\n+    assertOnError(reply->query(), msg);\n+}\n+//-------------------------------------------GET-----------------------------------------\n+//--OUTER--\n+template<class type> void SyncRGet(ICodeContext * ctx, const char * options, const char * key, type & returnValue, unsigned __int64 database, const char * pswd, unsigned __int64 _timeout)\n+{\n+    Owned<SyncConnection> master = SyncConnection::createConnection(ctx, options, database, pswd, _timeout);\n+    master->get(ctx, key, returnValue);\n+}\n+template<class type> void SyncRGet(ICodeContext * ctx, const char * options, const char * key, size_t & returnLength, type * & returnValue, unsigned __int64 database, const char * pswd, unsigned __int64 _timeout)\n+{\n+    Owned<SyncConnection> master = SyncConnection::createConnection(ctx, options, database, pswd, _timeout);\n+    master->get(ctx, key, returnLength, returnValue);\n+}\n+void SyncRGetVoidPtrLenPair(ICodeContext * ctx, const char * options, const char * key, size_t & returnLength, void * & returnValue, unsigned __int64 database, const char * pswd, unsigned __int64 _timeout)","path":"plugins/redis/redissync.cpp","position":253,"original_position":253,"commit_id":"fa2f212f3c83b8468703fe16649baa1630973625","original_commit_id":"fa2f212f3c83b8468703fe16649baa1630973625","user":{"login":"ghalliday","id":902490,"avatar_url":"https://avatars.githubusercontent.com/u/902490?v=3","gravatar_id":"","url":"https://api.github.com/users/ghalliday","html_url":"https://github.com/ghalliday","followers_url":"https://api.github.com/users/ghalliday/followers","following_url":"https://api.github.com/users/ghalliday/following{/other_user}","gists_url":"https://api.github.com/users/ghalliday/gists{/gist_id}","starred_url":"https://api.github.com/users/ghalliday/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ghalliday/subscriptions","organizations_url":"https://api.github.com/users/ghalliday/orgs","repos_url":"https://api.github.com/users/ghalliday/repos","events_url":"https://api.github.com/users/ghalliday/events{/privacy}","received_events_url":"https://api.github.com/users/ghalliday/received_events","type":"User","site_admin":false},"body":"trivial: I don't think this function is needed SyncRGet could be used instead.  (Now that simple types no longer pass a length.)","created_at":"2015-02-23T11:44:16Z","updated_at":"2015-02-23T11:44:16Z","html_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/6977#discussion_r25157997","pull_request_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977","_links":{"self":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments/25157997"},"html":{"href":"https://github.com/hpcc-systems/HPCC-Platform/pull/6977#discussion_r25157997"},"pull_request":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977"}}},"pull_request":{"url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977","id":29265519,"html_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/6977","diff_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/6977.diff","patch_url":"https://github.com/hpcc-systems/HPCC-Platform/pull/6977.patch","issue_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/6977","number":6977,"state":"open","locked":false,"title":"HPCC-13047 Redis plugin sync module","user":{"login":"jamienoss","id":5013975,"avatar_url":"https://avatars.githubusercontent.com/u/5013975?v=3","gravatar_id":"","url":"https://api.github.com/users/jamienoss","html_url":"https://github.com/jamienoss","followers_url":"https://api.github.com/users/jamienoss/followers","following_url":"https://api.github.com/users/jamienoss/following{/other_user}","gists_url":"https://api.github.com/users/jamienoss/gists{/gist_id}","starred_url":"https://api.github.com/users/jamienoss/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamienoss/subscriptions","organizations_url":"https://api.github.com/users/jamienoss/orgs","repos_url":"https://api.github.com/users/jamienoss/repos","events_url":"https://api.github.com/users/jamienoss/events{/privacy}","received_events_url":"https://api.github.com/users/jamienoss/received_events","type":"User","site_admin":false},"body":"Signed-off-by: james <james.noss@lexisnexis.com>","created_at":"2015-02-13T13:50:11Z","updated_at":"2015-02-23T11:44:16Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3465dd0746820be29cfd52a7a1383f7fda83b02b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977/commits","review_comments_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977/comments","review_comment_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/6977/comments","statuses_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/statuses/fa2f212f3c83b8468703fe16649baa1630973625","head":{"label":"jamienoss:issue13047-support-redis-5.2-sync","ref":"issue13047-support-redis-5.2-sync","sha":"fa2f212f3c83b8468703fe16649baa1630973625","user":{"login":"jamienoss","id":5013975,"avatar_url":"https://avatars.githubusercontent.com/u/5013975?v=3","gravatar_id":"","url":"https://api.github.com/users/jamienoss","html_url":"https://github.com/jamienoss","followers_url":"https://api.github.com/users/jamienoss/followers","following_url":"https://api.github.com/users/jamienoss/following{/other_user}","gists_url":"https://api.github.com/users/jamienoss/gists{/gist_id}","starred_url":"https://api.github.com/users/jamienoss/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamienoss/subscriptions","organizations_url":"https://api.github.com/users/jamienoss/orgs","repos_url":"https://api.github.com/users/jamienoss/repos","events_url":"https://api.github.com/users/jamienoss/events{/privacy}","received_events_url":"https://api.github.com/users/jamienoss/received_events","type":"User","site_admin":false},"repo":{"id":12548948,"name":"HPCC-Platform","full_name":"jamienoss/HPCC-Platform","owner":{"login":"jamienoss","id":5013975,"avatar_url":"https://avatars.githubusercontent.com/u/5013975?v=3","gravatar_id":"","url":"https://api.github.com/users/jamienoss","html_url":"https://github.com/jamienoss","followers_url":"https://api.github.com/users/jamienoss/followers","following_url":"https://api.github.com/users/jamienoss/following{/other_user}","gists_url":"https://api.github.com/users/jamienoss/gists{/gist_id}","starred_url":"https://api.github.com/users/jamienoss/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamienoss/subscriptions","organizations_url":"https://api.github.com/users/jamienoss/orgs","repos_url":"https://api.github.com/users/jamienoss/repos","events_url":"https://api.github.com/users/jamienoss/events{/privacy}","received_events_url":"https://api.github.com/users/jamienoss/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jamienoss/HPCC-Platform","description":"IMPORTANT - Issue tracking has been migrated to JIRA - use your github ID and password reset mechanism to log in","fork":true,"url":"https://api.github.com/repos/jamienoss/HPCC-Platform","forks_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/forks","keys_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/teams","hooks_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/hooks","issue_events_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/issues/events{/number}","events_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/events","assignees_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/assignees{/user}","branches_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/branches{/branch}","tags_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/tags","blobs_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/statuses/{sha}","languages_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/languages","stargazers_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/stargazers","contributors_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/contributors","subscribers_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/subscribers","subscription_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/subscription","commits_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/contents/{+path}","compare_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/merges","archive_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/downloads","issues_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/issues{/number}","pulls_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/pulls{/number}","milestones_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/milestones{/number}","notifications_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/labels{/name}","releases_url":"https://api.github.com/repos/jamienoss/HPCC-Platform/releases{/id}","created_at":"2013-09-02T20:57:07Z","updated_at":"2014-12-20T18:48:40Z","pushed_at":"2015-02-20T14:52:41Z","git_url":"git://github.com/jamienoss/HPCC-Platform.git","ssh_url":"git@github.com:jamienoss/HPCC-Platform.git","clone_url":"https://github.com/jamienoss/HPCC-Platform.git","svn_url":"https://github.com/jamienoss/HPCC-Platform","homepage":"track.hpccsystems.com","size":135718,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"hpcc-systems:candidate-5.2.0","ref":"candidate-5.2.0","sha":"28d3d70fee3b662c15998930fa662389d9eaa1b1","user":{"login":"hpcc-systems","id":900867,"avatar_url":"https://avatars.githubusercontent.com/u/900867?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcc-systems","html_url":"https://github.com/hpcc-systems","followers_url":"https://api.github.com/users/hpcc-systems/followers","following_url":"https://api.github.com/users/hpcc-systems/following{/other_user}","gists_url":"https://api.github.com/users/hpcc-systems/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcc-systems/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcc-systems/subscriptions","organizations_url":"https://api.github.com/users/hpcc-systems/orgs","repos_url":"https://api.github.com/users/hpcc-systems/repos","events_url":"https://api.github.com/users/hpcc-systems/events{/privacy}","received_events_url":"https://api.github.com/users/hpcc-systems/received_events","type":"Organization","site_admin":false},"repo":{"id":2030681,"name":"HPCC-Platform","full_name":"hpcc-systems/HPCC-Platform","owner":{"login":"hpcc-systems","id":900867,"avatar_url":"https://avatars.githubusercontent.com/u/900867?v=3","gravatar_id":"","url":"https://api.github.com/users/hpcc-systems","html_url":"https://github.com/hpcc-systems","followers_url":"https://api.github.com/users/hpcc-systems/followers","following_url":"https://api.github.com/users/hpcc-systems/following{/other_user}","gists_url":"https://api.github.com/users/hpcc-systems/gists{/gist_id}","starred_url":"https://api.github.com/users/hpcc-systems/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hpcc-systems/subscriptions","organizations_url":"https://api.github.com/users/hpcc-systems/orgs","repos_url":"https://api.github.com/users/hpcc-systems/repos","events_url":"https://api.github.com/users/hpcc-systems/events{/privacy}","received_events_url":"https://api.github.com/users/hpcc-systems/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/hpcc-systems/HPCC-Platform","description":"IMPORTANT - Issue tracking has been migrated to JIRA - use your github ID and password reset mechanism to log in","fork":false,"url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform","forks_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/forks","keys_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/teams","hooks_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/hooks","issue_events_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/events{/number}","events_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/events","assignees_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/assignees{/user}","branches_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/branches{/branch}","tags_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/tags","blobs_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/statuses/{sha}","languages_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/languages","stargazers_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/stargazers","contributors_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/contributors","subscribers_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/subscribers","subscription_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/subscription","commits_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/contents/{+path}","compare_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/merges","archive_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/downloads","issues_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues{/number}","pulls_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls{/number}","milestones_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/milestones{/number}","notifications_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/labels{/name}","releases_url":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/releases{/id}","created_at":"2011-07-11T14:29:51Z","updated_at":"2015-02-21T12:42:03Z","pushed_at":"2015-02-22T09:14:09Z","git_url":"git://github.com/hpcc-systems/HPCC-Platform.git","ssh_url":"git@github.com:hpcc-systems/HPCC-Platform.git","clone_url":"https://github.com/hpcc-systems/HPCC-Platform.git","svn_url":"https://github.com/hpcc-systems/HPCC-Platform","homepage":"track.hpccsystems.com","size":268867,"stargazers_count":243,"watchers_count":243,"language":"C++","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":96,"mirror_url":null,"open_issues_count":421,"forks":96,"open_issues":421,"watchers":243,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977"},"html":{"href":"https://github.com/hpcc-systems/HPCC-Platform/pull/6977"},"issue":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/6977"},"comments":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/issues/6977/comments"},"review_comments":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977/comments"},"review_comment":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/pulls/6977/commits"},"statuses":{"href":"https://api.github.com/repos/hpcc-systems/HPCC-Platform/statuses/fa2f212f3c83b8468703fe16649baa1630973625"}}}}