From 53cbb0d66cc4e6308a802ce5ed7268c150fe0648 Mon Sep 17 00:00:00 2001
From: rod-lin <zl38@illinois.edu>
Date: Wed, 27 Mar 2019 18:57:50 -0500
Subject: [PATCH 1/7] add worker id

---
 grader/api_keys.py |  2 +-
 grader/utils.py    |  4 ++--
 run.py             | 33 +++++++++++++++++----------------
 3 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/grader/api_keys.py b/grader/api_keys.py
index 5863ae8..0ec67a6 100644
--- a/grader/api_keys.py
+++ b/grader/api_keys.py
@@ -1,6 +1,6 @@
 # API keys
 AUTH = "Authorization"
-WORKER_ID = "worker_id"
+HOSTNAME = "hostname"
 HEARTBEAT = "heartbeat"
 GRADING_JOB_ID = "grading_job_id"
 RESULTS = "results"
diff --git a/grader/utils.py b/grader/utils.py
index 9b3373f..254da97 100644
--- a/grader/utils.py
+++ b/grader/utils.py
@@ -2,10 +2,10 @@
 
 
 def get_url(endpoint):
-    return "https://{}:{}{}{}".format(API_HOSTNAME, API_PORT, API_PROXY, endpoint)
+    return "http://{}:{}{}{}".format(API_HOSTNAME, API_PORT, API_PROXY, endpoint)
 
 
 def print_usage():
     print(
-        "Wrong number of arguments provided. Usage:\n\tpython grader.py <cluster token>"
+        "Wrong number of arguments provided. Usage:\n\tpython grader.py <cluster token> <worker id>"
     )
diff --git a/run.py b/run.py
index a9e23b5..90652ef 100644
--- a/run.py
+++ b/run.py
@@ -17,7 +17,9 @@
 
 # globals
 worker_id = None
+hostname = None
 worker_thread = None
+heartbeat_interval = HEARTBEAT_INTERVAL
 heartbeat_running = True
 worker_running = True
 event_loop = asyncio.new_event_loop()
@@ -52,7 +54,7 @@ def heartbeat_routine():
             logger.critical("Heartbeat failed!\nError: {}".format(response.text))
             return
 
-        time.sleep(HEARTBEAT_INTERVAL)
+        time.sleep(heartbeat_interval)
 
 
 def worker_routine():
@@ -141,9 +143,10 @@ def register_node():
     global worker_running
     global heartbeat_running
 
-    response = requests.get(
-        get_url("{}/{}".format(GRADER_REGISTER_ENDPOINT, socket.gethostname())),
+    response = requests.post(
+        get_url("{}/{}".format(GRADER_REGISTER_ENDPOINT, worker_id)),
         headers=header,
+        json={api_key.HOSTNAME: hostname}
     )
     if response.status_code != SUCCESS_CODE:
         logger.critical("Registration failed!\nError: {}".format(response.text))
@@ -153,30 +156,28 @@ def register_node():
 
     logger.info("Registered to server")
     server_response = response.json()["data"]
-    # read worker id
-    if api_key.WORKER_ID in server_response:
-        worker_id = server_response.get(api_key.WORKER_ID)
+    
+    # set heartbeat interval
+    if api_key.HEARTBEAT in server_response:
+        heartbeat_interval = server_response[api_key.HEARTBEAT]
     else:
-        logger.critical(
-            "Bad server response on registration. Missing argument '{}'.".format(
-                api_key.WORKER_ID
-            )
-        )
-        worker_running = False
-        heartbeat_running = False
-        exit(-1)
+        logger.info("Server response did not include heartbeat, using default {}".format(heartbeat_interval))
 
 
 if __name__ == "__main__":
     # check valid usage
-    if len(sys.argv) != 2:
+    if len(sys.argv) != 3:
         print_usage()
         exit(-1)
 
     signal.signal(signal.SIGINT, signal_handler)
 
+    token = sys.argv[1]
+    worker_id = sys.argv[2]
+    hostname = socket.gethostname()
+
     # register node to server
-    header = {api_key.AUTH: "Bearer {}".format(sys.argv[1])}
+    header = {api_key.AUTH: "Bearer {}".format(token)}
     register_node()
 
     # run the grader on two separate threads. If any of the routines fail, the grader shuts down

From 0c7f5ac6a4a65f6634bf1dc5ac96fc6f85913d99 Mon Sep 17 00:00:00 2001
From: rod-lin <zl38@illinois.edu>
Date: Thu, 28 Mar 2019 10:28:16 -0500
Subject: [PATCH 2/7] fix utils.py

---
 grader/utils.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/grader/utils.py b/grader/utils.py
index 254da97..6736d19 100644
--- a/grader/utils.py
+++ b/grader/utils.py
@@ -2,7 +2,7 @@
 
 
 def get_url(endpoint):
-    return "http://{}:{}{}{}".format(API_HOSTNAME, API_PORT, API_PROXY, endpoint)
+    return "https://{}:{}{}{}".format(API_HOSTNAME, API_PORT, API_PROXY, endpoint)
 
 
 def print_usage():

From 543e0f017a861f7c1af88bce65683a2cef3fbb49 Mon Sep 17 00:00:00 2001
From: Zhengyao <rod-lin@users.noreply.github.com>
Date: Thu, 28 Mar 2019 10:42:03 -0500
Subject: [PATCH 3/7] add PROTOCOL to config

---
 grader/api_keys.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/grader/api_keys.py b/grader/api_keys.py
index 0ec67a6..935dd48 100644
--- a/grader/api_keys.py
+++ b/grader/api_keys.py
@@ -2,6 +2,7 @@
 AUTH = "Authorization"
 HOSTNAME = "hostname"
 HEARTBEAT = "heartbeat"
+PROTOCOL = "https"
 GRADING_JOB_ID = "grading_job_id"
 RESULTS = "results"
 SUCCESS = "success"

From df904284dd3fecfea4c939ec5cac8b902223594b Mon Sep 17 00:00:00 2001
From: Zhengyao <rod-lin@users.noreply.github.com>
Date: Thu, 28 Mar 2019 10:44:54 -0500
Subject: [PATCH 4/7] add PROTOCOL to config

---
 grader/utils.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/grader/utils.py b/grader/utils.py
index 6736d19..9b827ec 100644
--- a/grader/utils.py
+++ b/grader/utils.py
@@ -1,8 +1,8 @@
-from config import API_HOSTNAME, API_PORT, API_PROXY
+from config import API_HOSTNAME, API_PORT, API_PROXY, PROTOCOL
 
 
 def get_url(endpoint):
-    return "https://{}:{}{}{}".format(API_HOSTNAME, API_PORT, API_PROXY, endpoint)
+    return "{}://{}:{}{}{}".format(PROTOCOL, API_HOSTNAME, API_PORT, API_PROXY, endpoint)
 
 
 def print_usage():

From 5b41f54801ec7bc1524c2ea30a9ba7151104fee0 Mon Sep 17 00:00:00 2001
From: rod-lin <zl38@illinois.edu>
Date: Thu, 28 Mar 2019 16:30:10 -0500
Subject: [PATCH 5/7] fix https

---
 config.py          | 1 +
 grader/api_keys.py | 1 -
 grader/utils.py    | 4 ++--
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/config.py b/config.py
index b8bf4ad..a0729df 100644
--- a/config.py
+++ b/config.py
@@ -10,6 +10,7 @@
 JOB_POLL_INTERVAL = 5
 
 # API endpoints
+USE_SSL = True
 HEARTBEAT_ENDPOINT = "/api/v1/heartbeat"
 GRADING_JOB_ENDPOINT = "/api/v1/grading_job"
 GRADER_REGISTER_ENDPOINT = "/api/v1/worker"
diff --git a/grader/api_keys.py b/grader/api_keys.py
index 935dd48..0ec67a6 100644
--- a/grader/api_keys.py
+++ b/grader/api_keys.py
@@ -2,7 +2,6 @@
 AUTH = "Authorization"
 HOSTNAME = "hostname"
 HEARTBEAT = "heartbeat"
-PROTOCOL = "https"
 GRADING_JOB_ID = "grading_job_id"
 RESULTS = "results"
 SUCCESS = "success"
diff --git a/grader/utils.py b/grader/utils.py
index 9b827ec..5548676 100644
--- a/grader/utils.py
+++ b/grader/utils.py
@@ -1,8 +1,8 @@
-from config import API_HOSTNAME, API_PORT, API_PROXY, PROTOCOL
+from config import API_HOSTNAME, API_PORT, API_PROXY, USE_SSL
 
 
 def get_url(endpoint):
-    return "{}://{}:{}{}{}".format(PROTOCOL, API_HOSTNAME, API_PORT, API_PROXY, endpoint)
+    return "{}://{}:{}{}{}".format("https" if USE_SSL else "http", API_HOSTNAME, API_PORT, API_PROXY, endpoint)
 
 
 def print_usage():

From 11e0714907094ca41c023ebc7c28203a3f354e1b Mon Sep 17 00:00:00 2001
From: rod-lin <zl38@illinois.edu>
Date: Fri, 29 Mar 2019 17:10:07 -0500
Subject: [PATCH 6/7] fix cmd-line args

---
 grader/utils.py |  6 ------
 run.py          | 18 ++++++++++++------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/grader/utils.py b/grader/utils.py
index 5548676..abc6e82 100644
--- a/grader/utils.py
+++ b/grader/utils.py
@@ -3,9 +3,3 @@
 
 def get_url(endpoint):
     return "{}://{}:{}{}{}".format("https" if USE_SSL else "http", API_HOSTNAME, API_PORT, API_PROXY, endpoint)
-
-
-def print_usage():
-    print(
-        "Wrong number of arguments provided. Usage:\n\tpython grader.py <cluster token> <worker id>"
-    )
diff --git a/run.py b/run.py
index 90652ef..d335671 100644
--- a/run.py
+++ b/run.py
@@ -5,6 +5,7 @@
 import socket
 import sys
 import time
+import argparse
 from concurrent.futures import ThreadPoolExecutor, wait, FIRST_COMPLETED
 from logging.handlers import TimedRotatingFileHandler
 
@@ -13,7 +14,7 @@
 
 import grader.api_keys as api_key
 from config import *
-from grader.utils import get_url, print_usage
+from grader.utils import get_url
 
 # globals
 worker_id = None
@@ -164,16 +165,21 @@ def register_node():
         logger.info("Server response did not include heartbeat, using default {}".format(heartbeat_interval))
 
 
+def parse_args():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("token", help="Broadway cluster token")
+    parser.add_argument("worker_id", metavar="worker-id", help="Unique worker id for registration")
+    return parser.parse_args()
+
+
 if __name__ == "__main__":
     # check valid usage
-    if len(sys.argv) != 3:
-        print_usage()
-        exit(-1)
+    args = parse_args()
 
     signal.signal(signal.SIGINT, signal_handler)
 
-    token = sys.argv[1]
-    worker_id = sys.argv[2]
+    token = args.token
+    worker_id = args.worker_id
     hostname = socket.gethostname()
 
     # register node to server

From b4b64b3be5a4ca2f70c2240c80c4fe42d2ffa37f Mon Sep 17 00:00:00 2001
From: rod-lin <zl38@illinois.edu>
Date: Fri, 29 Mar 2019 18:22:09 -0500
Subject: [PATCH 7/7] improve readability

---
 run.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/run.py b/run.py
index d335671..24ed92e 100644
--- a/run.py
+++ b/run.py
@@ -178,12 +178,11 @@ def parse_args():
 
     signal.signal(signal.SIGINT, signal_handler)
 
-    token = args.token
     worker_id = args.worker_id
     hostname = socket.gethostname()
 
     # register node to server
-    header = {api_key.AUTH: "Bearer {}".format(token)}
+    header = {api_key.AUTH: "Bearer {}".format(args.token)}
     register_node()
 
     # run the grader on two separate threads. If any of the routines fail, the grader shuts down