-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ci busy no more #143
Ci busy no more #143
Changes from 7 commits
74676e5
3a97ae4
ef255d0
8ba65de
3a1874b
bf5e2a8
17882a6
1c2f52d
29bbef6
a1749cb
0c3a90b
45fdf70
c10dbb4
5b06b38
12935e3
b771745
04380b1
e7639ef
ed65879
3b01660
58a13ff
4bef1aa
05a89f8
24965be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,8 @@ | |
import os | ||
import subprocess | ||
import logging | ||
import time | ||
import threading | ||
|
||
# Global vars | ||
EVENT_URL = "/github-webhook" | ||
|
@@ -23,6 +25,8 @@ | |
secret_file_name = None | ||
private_key_file = None | ||
secret = None | ||
queue_lock = None | ||
ci_request_list = None | ||
|
||
app = Flask(__name__) | ||
|
||
|
@@ -158,6 +162,20 @@ def filter_to_prs_and_pr_comments(json): | |
|
||
return None | ||
|
||
# run the manager, and rest of CI process | ||
def run_manager(request_ctx): | ||
log_access_granted(request_ctx, "Running CI") | ||
os.system("./manager.sh config {} \"{}\" \"{}\"".format(request_ctx['id'], request_ctx['repo'], request_ctx['body'])) | ||
|
||
def poll_request_list(): | ||
while True: | ||
# continuously check for waiting requests | ||
if len(ci_request_list) > 0: | ||
run_manager(ci_request_list.pop(0)) | ||
else: | ||
# no requests, sleep | ||
time.sleep(1) | ||
|
||
@app.route(EVENT_URL, methods=['POST']) | ||
def init_ci_pipeline(): | ||
request_ctx = filter_to_prs_and_pr_comments(request.json) | ||
|
@@ -196,13 +214,28 @@ def init_ci_pipeline(): | |
out, err = proc2.communicate() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically if CI has finished a run and is in the middle of spawning a call this out value will be wrong anyway, why don't we use that + length of ci request queue to properly determine if we can run instantly |
||
|
||
if (out): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think there is any reason to separate this into 2 branches. lets just always do the one that grabs the queue_lock and does w.e processing it needs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. even with changing it so we check the "out" logic with ci_request_list.length > 0, how can we ignore the else condition? Why would we want to "nuke" that? |
||
print("Can't run CI, another CI run in progress") | ||
log_access_granted(request_ctx, "CI busy, posting busy msg") | ||
os.system("./ci_busy.sh config {} \"{}\" \"{}\" \"Another CI run in progress, please try again in 15 minutes\"" | ||
.format(request_ctx['id'], request_ctx['repo'], request_ctx['body'])) | ||
print("Can't run CI, another CI run in progress, placing in the queue") | ||
log_access_granted(request_ctx, "CI busy, placing request in queue") | ||
duplicate_req = False | ||
busy_msg = "Duplicate request already waiting, ignoring message" | ||
# make sure we don't bypass thread safety | ||
with queue_lock: | ||
for req in ci_request_list: | ||
# make sure this is the same PR | ||
if req['id'] == request_ctx['id'] and req['repo'] == request_ctx['repo']: | ||
duplicate_req = True | ||
break | ||
if not duplicate_req: | ||
# don't have this request yet, put in queue | ||
ci_request_list.append(request_ctx) | ||
busy_msg = "Another CI run in progress, adding request to the end of the list" | ||
# ending frees the lock | ||
os.system("./ci_busy.sh config {} \"{}\" \"{}\" \"{}\"" | ||
koolzz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.format(request_ctx['id'], request_ctx['repo'], request_ctx['body'], busy_msg)) | ||
else: | ||
log_access_granted(request_ctx, "Running CI") | ||
os.system("./manager.sh config {} \"{}\" \"{}\"".format(request_ctx['id'], request_ctx['repo'], request_ctx['body'])) | ||
# no manager running yet, put in the list (presumably the top) | ||
with queue_lock: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nuke this branch, combine with above |
||
ci_request_list.append(request_ctx) | ||
|
||
return jsonify({"status": "ONLINE"}) | ||
|
||
|
@@ -251,8 +284,15 @@ def parse_config(cfg_name): | |
cfg_name = sys.argv[4] | ||
|
||
parse_config(cfg_name) | ||
|
||
secret = decrypt_secret() | ||
queue_lock = threading.Lock() | ||
ci_request_list = [] | ||
|
||
# dedicate thread to check for and run new requests | ||
poll_request = threading.Thread(target=poll_request_list, args=[]) | ||
# run as daemon to catch ^C termination | ||
poll_request.daemon = True | ||
poll_request.start() | ||
|
||
logging.info("Starting the CI service") | ||
app.run(host=host, port=port) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Figured we could just sleep for a second, but not sure how long is best
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might want a sleeping queue sort of implementation in the future, but good enough for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you mean?