Skip to content

Commit 74ff82c

Browse files
authored
Merge pull request #14 from domonik/dev
puts tasks in independent background
2 parents 14c2605 + 198d811 commit 74ff82c

File tree

3 files changed

+75
-27
lines changed

3 files changed

+75
-27
lines changed

RNAdist/dashboard/assets/tableFix.css

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@
44
background: #fff;
55
}
66

7+
8+
.dash-spreadsheet-container .dash-spreadsheet-inner table .dash-cell.active {
9+
background-color: inherit !important;
10+
border: inherit !important;
11+
}
12+
13+
/* Prevent background color change on selected cell */
14+
.dash-spreadsheet-container .dash-spreadsheet-inner table .dash-cell.selected {
15+
background-color: inherit !important;
16+
border: inherit !important;
17+
}
18+
719
.nav-link.active {
820
font-weight: bold;
921
}
@@ -77,7 +89,6 @@ li {
7789

7890
body .dbc .dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner td {
7991
background-color: var(--bs-body-bg);
80-
color: var(--bs-body-color);
8192
border: none !important;
8293
padding: 10px 10px 10px 10px;
8394
}

RNAdist/dashboard/helpers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ def matrix_from_hash(self, md_hash, return_mfe: bool = False):
257257
def set_status(self, hash_value, status, user_id, header):
258258
"""Insert or update a job's status."""
259259
with self.engine.begin() as conn:
260-
logger.info(f"Setting status: {hash_value} to {status}")
261260
conn.execute(
262261
text("""
263262
INSERT INTO jobs (hash, status, user_id, header)

RNAdist/dashboard/pages/submission.py

Lines changed: 63 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import RNA
44
import dash
5-
from dash import callback, html, clientside_callback, Input, Output, dcc, dash_table, State, Patch
5+
from dash import callback, html, clientside_callback, Input, Output, dcc, dash_table, State, Patch, ALL, ctx
66
import dash_bootstrap_components as dbc
77
from RNAdist.dashboard import MAX_SEQ_LENGTH, CONFIG
88
from RNAdist.sampling.ed_sampling import distance_histogram
9+
from RNAdist.dashboard.backends import celery
910
from RNAdist.plots.sampling_plots import distance_histo_from_matrix
1011
import sqlite3
1112
import numpy as np
@@ -68,11 +69,26 @@ def get_submissions_table():
6869
'backgroundColor': 'var(--bs-tertiary-bg)',
6970
},
7071
{
71-
'if': {'column_id': 'Header'},
72-
'color': 'var(--bs-secondary)', # use Bootstrap link color variable
72+
'if': {
73+
'column_id': 'Header',
74+
'filter_query': '{Status} = "finished"' # only style if status is finished
75+
},
76+
'color': 'var(--bs-secondary)', # Bootstrap link color variable
7377
'textDecoration': 'underline',
7478
'cursor': 'pointer',
75-
}
79+
},
80+
{
81+
"if": {"state": "active"},
82+
"backgroundColor": "inherit !important",
83+
"border": "inherit !important",
84+
"color": "red"
85+
},
86+
{
87+
"if": {"column_id": "Header", "filter_query": '{Status} = "finished"'},
88+
"color": "var(--bs-secondary)",
89+
"textDecoration": "underline",
90+
"cursor": "pointer",
91+
},
7692

7793
],
7894
style_header={
@@ -98,6 +114,7 @@ def get_submissions_table():
98114
'overflow': 'hidden',
99115
'textOverflow': 'ellipsis',
100116
'whiteSpace': 'nowrap',
117+
"userSelect": "none"
101118
},
102119
),
103120

@@ -309,6 +326,8 @@ def check_valid_input(sequence, temperature, bpspan, user_id, header):
309326
310327
)
311328
def submit_sequence(n_clicks, sequence, header, user_id, temperature, max_bp_span, is_open):
329+
print("triggered:", ctx.triggered_id)
330+
312331
if n_clicks is None:
313332
raise dash.exceptions.PreventUpdate
314333

@@ -346,37 +365,58 @@ def submit_sequence(n_clicks, sequence, header, user_id, temperature, max_bp_spa
346365
return [header, fields, sequence], is_open, dash.no_update
347366

348367

349-
@callback(
350-
output=Output("sequence-computation-finished", "data"),
351-
inputs=Input("submitted-job", "data"),
352-
state=[
353-
State("user_id", "data"),
354-
],
355-
background=True,
356-
prevent_initial_call=True
357-
)
358-
def process_sequence(submitted_job, user_id):
359-
logger.info("STARTED long running task")
360368

361-
if submitted_job is None:
362-
return dash.no_update
369+
def _process_sequence_inline(submitted_job, user_id):
370+
"""Same code as your Celery task, for local execution without Redis."""
363371
DB.database_cleanup()
364372
header, md_dict, sequence = submitted_job
373+
logger.info(f"started processing sequence: {header}-{user_id}")
374+
365375
RNA.init_rand(42)
366376
md = RNA.md(**md_dict)
367377
fc = RNA.fold_compound(sequence, md)
368378
_, md_hash = hash_model_details(md, sequence)
369379
try:
370-
371380
DB.set_status(md_hash, "running", user_id, header)
372381
histograms, samples = distance_histogram(fc, 10000, return_samples=True)
373382
DB.compress_and_insert_into_submissions(sequence, histograms, samples, fc, md)
374383
DB.set_status(md_hash, "finished", user_id, header)
375384
except Exception as e:
376-
print("RUNNING")
377385
DB.set_status(md_hash, "failed", user_id, header)
378386
raise e
379-
logger.info(f"FINISHED long running task")
387+
logger.info(f"FINISHED long running task {header}-{user_id}")
388+
return True
389+
390+
if CONFIG["REDIS"]["URL"]:
391+
@celery.task(bind=True)
392+
def process_sequence_task(self, submitted_job, user_id):
393+
_process_sequence_inline(submitted_job, user_id)
394+
return True
395+
396+
else:
397+
process_sequence_task = _process_sequence_inline
398+
399+
@callback(
400+
output=Output("sequence-computation-finished", "data"),
401+
inputs=Input("submitted-job", "data"),
402+
state=[
403+
State("user_id", "data"),
404+
],
405+
running=[
406+
(Output("submit-sequence", "disabled"), True, False),
407+
] if not CONFIG["REDIS"]["URL"] else None,
408+
background=True if not CONFIG["REDIS"]["URL"] else False,
409+
prevent_initial_call="initial_duplicate",
410+
allow_duplicate=True,
411+
)
412+
def process_sequence(submitted_job, user_id):
413+
print("triggered:", ctx.triggered_id, submitted_job)
414+
if submitted_job is None:
415+
return dash.no_update
416+
if CONFIG["REDIS"]["URL"]:
417+
async_result = process_sequence_task.delay(submitted_job, user_id)
418+
else:
419+
process_sequence_task(submitted_job, user_id)
380420
return True
381421

382422
@callback(
@@ -390,12 +430,10 @@ def process_sequence(submitted_job, user_id):
390430
)
391431
def display_status(n, user_id, _, _2):
392432
status = DB.get_jobs_of_user(user_id)
393-
logger.info(f"status: {status}")
394433
table = []
395434
tooltips = []
396435
all_finished = True
397436
for row in status:
398-
logger.info(row)
399437
job_id = str(row["job_hash"].hex())
400438
state = row["status"]
401439
if state != "finished":
@@ -411,7 +449,6 @@ def display_status(n, user_id, _, _2):
411449
"Sequence": {"value": seq, "type": "text"} # tooltip shows full sequence on hover
412450
})
413451
row = {"Status": state, "Job ID": job_id, "Header": row["header"], "ModelDetails": model_details, "Sequence": seq}
414-
print(row)
415452
table.append(row)
416453

417454
interval_disabled = all_finished
@@ -423,6 +460,7 @@ def display_status(n, user_id, _, _2):
423460
Output("page-wide-seqid", "data"),
424461
Output('url', 'pathname'),
425462
Output("not-finished-modal", "is_open"),
463+
Output('submissions-table', 'active_cell'),
426464
Input('submissions-table', 'active_cell'),
427465
State('submissions-table', 'data'),
428466
)
@@ -436,6 +474,6 @@ def on_row_select(active_cell, data):
436474
if header_value is None:
437475
raise dash.exceptions.PreventUpdate
438476
if status != "finished":
439-
return dash.no_update, dash.no_update, True
477+
return dash.no_update, dash.no_update, True, None
440478

441-
return header_value, "visualization", dash.no_update
479+
return header_value, "visualization", dash.no_update, None

0 commit comments

Comments
 (0)