{"action":"created","comment":{"url":"https://api.github.com/repos/apache/incubator-quickstep/pulls/comments/112547038","pull_request_review_id":33714148,"id":112547038,"diff_hunk":"@@ -0,0 +1,227 @@\n+/**\n+ * Licensed to the Apache Software Foundation (ASF) under one\n+ * or more contributor license agreements.  See the NOTICE file\n+ * distributed with this work for additional information\n+ * regarding copyright ownership.  The ASF licenses this file\n+ * to you under the Apache License, Version 2.0 (the\n+ * \"License\"); you may not use this file except in compliance\n+ * with the License.  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,\n+ * software distributed under the License is distributed on an\n+ * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n+ * KIND, either express or implied.  See the License for the\n+ * specific language governing permissions and limitations\n+ * under the License.\n+ **/\n+\n+#ifndef QUICKSTEP_CLI_NETWORK_IO_HPP_\n+#define QUICKSTEP_CLI_NETWORK_IO_HPP_\n+\n+#include <grpc++/grpc++.h>\n+\n+#include <iostream>\n+#include <memory>\n+#include <string>\n+#include <vector>\n+\n+#include \"cli/Flags.hpp\"\n+#include \"cli/IOInterface.hpp\"\n+#include \"cli/NetworkCli.grpc.pb.h\"\n+#include \"cli/NetworkCli.pb.h\"\n+#include \"threading/ConditionVariable.hpp\"\n+#include \"threading/Mutex.hpp\"\n+#include \"utility/MemStream.hpp\"\n+\n+#include \"gflags/gflags.h\"\n+#include \"glog/logging.h\"\n+\n+using grpc::Channel;\n+using grpc::ClientContext;\n+using grpc::Server;\n+using grpc::Status;\n+\n+namespace quickstep {\n+\n+namespace networkio_internal {\n+\n+/**\n+ * Contains state and helper methods for managing interactions between a producer/consumer (requestor/requestee)\n+ * thread.\n+ */\n+class RequestState {\n+ public:\n+  RequestState() :\n+    request_ready_(false),\n+    response_ready_(false),\n+    request_buffer_(\"\"),\n+    mutex_(),\n+    condition_() {}\n+\n+  /**\n+   * Notifies waiter that a piece of work has been created and added to the buffer.\n+   * @param to_consume The arguments for the consuming thread.\n+   */\n+  void requestReady(std::string to_consume) {\n+    request_ready_ = true;\n+    response_ready_ = false;\n+    request_buffer_ = to_consume;\n+    condition_.notify_one();\n+  }\n+\n+  /**\n+   * Notifies that the consumer has finished consuming and that a response is ready.\n+   * To be called after the consumer has executed.\n+   */\n+  void responseReady() {\n+    request_ready_ = false;\n+    response_ready_ = true;\n+    condition_.notify_one();\n+  }\n+\n+  bool request_ready_;\n+  bool response_ready_;\n+  std::string request_buffer_;\n+  QueryResponse response_message_;\n+  std::mutex mutex_;\n+  std::condition_variable condition_;\n+};\n+}  // namespace networkio_internal\n+\n+class NetworkCliServiceImpl final : public NetworkCli::Service {\n+ public:\n+  NetworkCliServiceImpl()\n+    : NetworkCli::Service(),\n+      worker_exclusive_mtx_(),\n+      running_(true),\n+      request_state_() { }\n+\n+  /**\n+   * Handles gRPC request. Sets the buffer in the RequestState, notifies the main thread, then waits for a response.\n+   * @param context\n+   * @param request\n+   * @param response\n+   * @return\n+   */\n+  Status SendQuery(grpc::ServerContext *context,\n+                   const QueryRequest *request,\n+                   QueryResponse *response) override {\n+    auto service_ex_lock = enter();\n+    if (!service_ex_lock) {\n+      return Status::CANCELLED;\n+    }\n+\n+    // Service thread sets a notification for the main thread.\n+    // Because of service thread exclusivity, we have rights to this data structure.\n+    request_state_.requestReady(request->query());\n+\n+    // Service thread - main thread critical section:\n+    // Service thread waits for the buffered message response from the main thread. The main thread will set\n+    // consumer_ready_ when it is finished and released its exclusive lock on the communication data structure.\n+    std::unique_lock<std::mutex> lock(request_state_.mutex_);\n+    while (!request_state_.response_ready_)\n+      request_state_.condition_.wait(lock);\n+\n+    *response = request_state_.response_message_;\n+\n+    return Status::OK;\n+  }\n+\n+  void kill() {\n+    running_ = false;\n+  }\n+\n+  networkio_internal::RequestState& getRequestState() {\n+    return request_state_;\n+  }\n+\n+ private:\n+  /**\n+   * When a worker enters, it gains exclusive access to the main thread. That is, no other worker of this service\n+   * is allowed to interact with main thread.\n+   * @return A lock which grants the worker mutual exclusion.\n+   */\n+  std::unique_lock<std::mutex> enter() {\n+    std::unique_lock<std::mutex> lock(worker_exclusive_mtx_);\n+    if (!running_)\n+      lock.unlock();\n+    return lock;\n+  }\n+\n+  std::mutex worker_exclusive_mtx_;\n+  bool running_;\n+  networkio_internal::RequestState request_state_;\n+};\n+\n+class NetworkIO : public IOInterface {\n+ public:\n+  NetworkIO()\n+      : IOInterface(),\n+        out_stream_(),\n+        err_stream_(),\n+        server_(nullptr),\n+        service_() {","path":"cli/NetworkIO.hpp","position":165,"original_position":165,"commit_id":"47d0055c47616277fc6af71369b58ad3869734af","original_commit_id":"45f0f1ca91e94b9d8fca45a4fa816d6fa9d030bd","user":{"login":"zuyu","id":2245572,"avatar_url":"https://avatars3.githubusercontent.com/u/2245572?v=3","gravatar_id":"","url":"https://api.github.com/users/zuyu","html_url":"https://github.com/zuyu","followers_url":"https://api.github.com/users/zuyu/followers","following_url":"https://api.github.com/users/zuyu/following{/other_user}","gists_url":"https://api.github.com/users/zuyu/gists{/gist_id}","starred_url":"https://api.github.com/users/zuyu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zuyu/subscriptions","organizations_url":"https://api.github.com/users/zuyu/orgs","repos_url":"https://api.github.com/users/zuyu/repos","events_url":"https://api.github.com/users/zuyu/events{/privacy}","received_events_url":"https://api.github.com/users/zuyu/received_events","type":"User","site_admin":false},"body":"No needs for explicitly calling default constructors.","created_at":"2017-04-20T20:00:22Z","updated_at":"2017-04-20T20:24:51Z","html_url":"https://github.com/apache/incubator-quickstep/pull/232#discussion_r112547038","pull_request_url":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232","_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-quickstep/pulls/comments/112547038"},"html":{"href":"https://github.com/apache/incubator-quickstep/pull/232#discussion_r112547038"},"pull_request":{"href":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232"}}},"pull_request":{"url":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232","id":116219936,"html_url":"https://github.com/apache/incubator-quickstep/pull/232","diff_url":"https://github.com/apache/incubator-quickstep/pull/232.diff","patch_url":"https://github.com/apache/incubator-quickstep/pull/232.patch","issue_url":"https://api.github.com/repos/apache/incubator-quickstep/issues/232","number":232,"state":"open","locked":false,"title":"QUICKSTEP-87 Adds network cli interface.","user":{"login":"cramja","id":5708822,"avatar_url":"https://avatars2.githubusercontent.com/u/5708822?v=3","gravatar_id":"","url":"https://api.github.com/users/cramja","html_url":"https://github.com/cramja","followers_url":"https://api.github.com/users/cramja/followers","following_url":"https://api.github.com/users/cramja/following{/other_user}","gists_url":"https://api.github.com/users/cramja/gists{/gist_id}","starred_url":"https://api.github.com/users/cramja/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cramja/subscriptions","organizations_url":"https://api.github.com/users/cramja/orgs","repos_url":"https://api.github.com/users/cramja/repos","events_url":"https://api.github.com/users/cramja/events{/privacy}","received_events_url":"https://api.github.com/users/cramja/received_events","type":"User","site_admin":false},"body":"# Adds Network CLI functionality to Single Node\r\n\r\n**Functional Changes include:**\r\n]Adding a network mode to the cli. Run quickstep in `network` mode (defaults to `local`)\r\n\r\n`quickstep_cli_shell --mode=network`\r\n\r\nNow quickstep boots a server, you can interact using the client executable...\r\n\r\n`quickstep_client < my_query.sql`\r\n\r\n**Code Changes include:**\r\n* Adds a generic IO interface\r\n  * Hides Linereader from CLI behind class `LocalIO`\r\n  * New `NetworkIO` also hidden here\r\n* Adds tests for NetworkIO\r\n* Adds simple Client executable \r\n* Cmake flag to disable (`ENABLE_NETWORK_CLI=false`)","created_at":"2017-04-17T23:00:47Z","updated_at":"2017-04-20T20:24:51Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d3dfde462fe307040e4df93db4ec0599274d7aa7","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232/commits","review_comments_url":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232/comments","review_comment_url":"https://api.github.com/repos/apache/incubator-quickstep/pulls/comments{/number}","comments_url":"https://api.github.com/repos/apache/incubator-quickstep/issues/232/comments","statuses_url":"https://api.github.com/repos/apache/incubator-quickstep/statuses/47d0055c47616277fc6af71369b58ad3869734af","head":{"label":"cramja:implements-network-cli","ref":"implements-network-cli","sha":"47d0055c47616277fc6af71369b58ad3869734af","user":{"login":"cramja","id":5708822,"avatar_url":"https://avatars2.githubusercontent.com/u/5708822?v=3","gravatar_id":"","url":"https://api.github.com/users/cramja","html_url":"https://github.com/cramja","followers_url":"https://api.github.com/users/cramja/followers","following_url":"https://api.github.com/users/cramja/following{/other_user}","gists_url":"https://api.github.com/users/cramja/gists{/gist_id}","starred_url":"https://api.github.com/users/cramja/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cramja/subscriptions","organizations_url":"https://api.github.com/users/cramja/orgs","repos_url":"https://api.github.com/users/cramja/repos","events_url":"https://api.github.com/users/cramja/events{/privacy}","received_events_url":"https://api.github.com/users/cramja/received_events","type":"User","site_admin":false},"repo":{"id":66734831,"name":"incubator-quickstep","full_name":"cramja/incubator-quickstep","owner":{"login":"cramja","id":5708822,"avatar_url":"https://avatars2.githubusercontent.com/u/5708822?v=3","gravatar_id":"","url":"https://api.github.com/users/cramja","html_url":"https://github.com/cramja","followers_url":"https://api.github.com/users/cramja/followers","following_url":"https://api.github.com/users/cramja/following{/other_user}","gists_url":"https://api.github.com/users/cramja/gists{/gist_id}","starred_url":"https://api.github.com/users/cramja/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cramja/subscriptions","organizations_url":"https://api.github.com/users/cramja/orgs","repos_url":"https://api.github.com/users/cramja/repos","events_url":"https://api.github.com/users/cramja/events{/privacy}","received_events_url":"https://api.github.com/users/cramja/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/cramja/incubator-quickstep","description":"Mirror of Apache Quickstep Incubator","fork":true,"url":"https://api.github.com/repos/cramja/incubator-quickstep","forks_url":"https://api.github.com/repos/cramja/incubator-quickstep/forks","keys_url":"https://api.github.com/repos/cramja/incubator-quickstep/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cramja/incubator-quickstep/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cramja/incubator-quickstep/teams","hooks_url":"https://api.github.com/repos/cramja/incubator-quickstep/hooks","issue_events_url":"https://api.github.com/repos/cramja/incubator-quickstep/issues/events{/number}","events_url":"https://api.github.com/repos/cramja/incubator-quickstep/events","assignees_url":"https://api.github.com/repos/cramja/incubator-quickstep/assignees{/user}","branches_url":"https://api.github.com/repos/cramja/incubator-quickstep/branches{/branch}","tags_url":"https://api.github.com/repos/cramja/incubator-quickstep/tags","blobs_url":"https://api.github.com/repos/cramja/incubator-quickstep/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cramja/incubator-quickstep/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cramja/incubator-quickstep/git/refs{/sha}","trees_url":"https://api.github.com/repos/cramja/incubator-quickstep/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cramja/incubator-quickstep/statuses/{sha}","languages_url":"https://api.github.com/repos/cramja/incubator-quickstep/languages","stargazers_url":"https://api.github.com/repos/cramja/incubator-quickstep/stargazers","contributors_url":"https://api.github.com/repos/cramja/incubator-quickstep/contributors","subscribers_url":"https://api.github.com/repos/cramja/incubator-quickstep/subscribers","subscription_url":"https://api.github.com/repos/cramja/incubator-quickstep/subscription","commits_url":"https://api.github.com/repos/cramja/incubator-quickstep/commits{/sha}","git_commits_url":"https://api.github.com/repos/cramja/incubator-quickstep/git/commits{/sha}","comments_url":"https://api.github.com/repos/cramja/incubator-quickstep/comments{/number}","issue_comment_url":"https://api.github.com/repos/cramja/incubator-quickstep/issues/comments{/number}","contents_url":"https://api.github.com/repos/cramja/incubator-quickstep/contents/{+path}","compare_url":"https://api.github.com/repos/cramja/incubator-quickstep/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cramja/incubator-quickstep/merges","archive_url":"https://api.github.com/repos/cramja/incubator-quickstep/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cramja/incubator-quickstep/downloads","issues_url":"https://api.github.com/repos/cramja/incubator-quickstep/issues{/number}","pulls_url":"https://api.github.com/repos/cramja/incubator-quickstep/pulls{/number}","milestones_url":"https://api.github.com/repos/cramja/incubator-quickstep/milestones{/number}","notifications_url":"https://api.github.com/repos/cramja/incubator-quickstep/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cramja/incubator-quickstep/labels{/name}","releases_url":"https://api.github.com/repos/cramja/incubator-quickstep/releases{/id}","deployments_url":"https://api.github.com/repos/cramja/incubator-quickstep/deployments","created_at":"2016-08-27T20:46:25Z","updated_at":"2016-08-27T20:46:30Z","pushed_at":"2017-04-20T14:23:54Z","git_url":"git://github.com/cramja/incubator-quickstep.git","ssh_url":"git@github.com:cramja/incubator-quickstep.git","clone_url":"https://github.com/cramja/incubator-quickstep.git","svn_url":"https://github.com/cramja/incubator-quickstep","homepage":null,"size":10268,"stargazers_count":0,"watchers_count":0,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"apache:master","ref":"master","sha":"3c83c937acd6d2484cfa7c96c21e695fd3cdaba3","user":{"login":"apache","id":47359,"avatar_url":"https://avatars3.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"repo":{"id":56214719,"name":"incubator-quickstep","full_name":"apache/incubator-quickstep","owner":{"login":"apache","id":47359,"avatar_url":"https://avatars3.githubusercontent.com/u/47359?v=3","gravatar_id":"","url":"https://api.github.com/users/apache","html_url":"https://github.com/apache","followers_url":"https://api.github.com/users/apache/followers","following_url":"https://api.github.com/users/apache/following{/other_user}","gists_url":"https://api.github.com/users/apache/gists{/gist_id}","starred_url":"https://api.github.com/users/apache/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apache/subscriptions","organizations_url":"https://api.github.com/users/apache/orgs","repos_url":"https://api.github.com/users/apache/repos","events_url":"https://api.github.com/users/apache/events{/privacy}","received_events_url":"https://api.github.com/users/apache/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/apache/incubator-quickstep","description":"Mirror of Apache Quickstep Incubator","fork":false,"url":"https://api.github.com/repos/apache/incubator-quickstep","forks_url":"https://api.github.com/repos/apache/incubator-quickstep/forks","keys_url":"https://api.github.com/repos/apache/incubator-quickstep/keys{/key_id}","collaborators_url":"https://api.github.com/repos/apache/incubator-quickstep/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/apache/incubator-quickstep/teams","hooks_url":"https://api.github.com/repos/apache/incubator-quickstep/hooks","issue_events_url":"https://api.github.com/repos/apache/incubator-quickstep/issues/events{/number}","events_url":"https://api.github.com/repos/apache/incubator-quickstep/events","assignees_url":"https://api.github.com/repos/apache/incubator-quickstep/assignees{/user}","branches_url":"https://api.github.com/repos/apache/incubator-quickstep/branches{/branch}","tags_url":"https://api.github.com/repos/apache/incubator-quickstep/tags","blobs_url":"https://api.github.com/repos/apache/incubator-quickstep/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/apache/incubator-quickstep/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/apache/incubator-quickstep/git/refs{/sha}","trees_url":"https://api.github.com/repos/apache/incubator-quickstep/git/trees{/sha}","statuses_url":"https://api.github.com/repos/apache/incubator-quickstep/statuses/{sha}","languages_url":"https://api.github.com/repos/apache/incubator-quickstep/languages","stargazers_url":"https://api.github.com/repos/apache/incubator-quickstep/stargazers","contributors_url":"https://api.github.com/repos/apache/incubator-quickstep/contributors","subscribers_url":"https://api.github.com/repos/apache/incubator-quickstep/subscribers","subscription_url":"https://api.github.com/repos/apache/incubator-quickstep/subscription","commits_url":"https://api.github.com/repos/apache/incubator-quickstep/commits{/sha}","git_commits_url":"https://api.github.com/repos/apache/incubator-quickstep/git/commits{/sha}","comments_url":"https://api.github.com/repos/apache/incubator-quickstep/comments{/number}","issue_comment_url":"https://api.github.com/repos/apache/incubator-quickstep/issues/comments{/number}","contents_url":"https://api.github.com/repos/apache/incubator-quickstep/contents/{+path}","compare_url":"https://api.github.com/repos/apache/incubator-quickstep/compare/{base}...{head}","merges_url":"https://api.github.com/repos/apache/incubator-quickstep/merges","archive_url":"https://api.github.com/repos/apache/incubator-quickstep/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/apache/incubator-quickstep/downloads","issues_url":"https://api.github.com/repos/apache/incubator-quickstep/issues{/number}","pulls_url":"https://api.github.com/repos/apache/incubator-quickstep/pulls{/number}","milestones_url":"https://api.github.com/repos/apache/incubator-quickstep/milestones{/number}","notifications_url":"https://api.github.com/repos/apache/incubator-quickstep/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/apache/incubator-quickstep/labels{/name}","releases_url":"https://api.github.com/repos/apache/incubator-quickstep/releases{/id}","deployments_url":"https://api.github.com/repos/apache/incubator-quickstep/deployments","created_at":"2016-04-14T07:00:07Z","updated_at":"2017-04-11T16:11:29Z","pushed_at":"2017-04-20T14:23:55Z","git_url":"git://github.com/apache/incubator-quickstep.git","ssh_url":"git@github.com:apache/incubator-quickstep.git","clone_url":"https://github.com/apache/incubator-quickstep.git","svn_url":"https://github.com/apache/incubator-quickstep","homepage":null,"size":10505,"stargazers_count":34,"watchers_count":34,"language":"C++","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":27,"mirror_url":"git://git.apache.org/incubator-quickstep.git","open_issues_count":2,"forks":27,"open_issues":2,"watchers":34,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232"},"html":{"href":"https://github.com/apache/incubator-quickstep/pull/232"},"issue":{"href":"https://api.github.com/repos/apache/incubator-quickstep/issues/232"},"comments":{"href":"https://api.github.com/repos/apache/incubator-quickstep/issues/232/comments"},"review_comments":{"href":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232/comments"},"review_comment":{"href":"https://api.github.com/repos/apache/incubator-quickstep/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/apache/incubator-quickstep/pulls/232/commits"},"statuses":{"href":"https://api.github.com/repos/apache/incubator-quickstep/statuses/47d0055c47616277fc6af71369b58ad3869734af"}}}}
{"actor":{"display_login":"zuyu"}}