Skip to content

Commit cc4fe68

Browse files
authored
Task: storage service rework (#30)
- Add finish_campaign endpoint to service (signal end of campaign) - upload stateful file when end of campaign is signaled
1 parent 593c1f0 commit cc4fe68

File tree

12 files changed

+204
-126
lines changed

12 files changed

+204
-126
lines changed

Dockerfile.storage_service

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ FROM python:3.10-slim
33

44
WORKDIR /usr/src/storage_service
55

6-
RUN python -m pip install python-dotenv boto3==1.35.99
6+
RUN python -m pip install python-dotenv boto3==1.35.99 pyyaml
77

8+
COPY ./config/config_storage.yaml /app/config_storage.yaml
89
COPY ./services/storage_service.py ./storage_service.py
910
COPY ./services/constants.py ./constants.py
1011

clients/realtime_client.py

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
default_intersect_lifecycle_loop,
2222
)
2323

24-
from schema import FileType, TransitionData, NextTemperature
24+
from schema import FileType, TransitionData, NextTemperature, FinishCampaignMsg
2525

2626
logging.basicConfig(level=logging.INFO)
2727

@@ -71,7 +71,28 @@ class SampleOrchestrator:
7171
def __init__(self) -> None:
7272
""" "Load all gsa files to simulate a stream of data coming in"""
7373
self.message_stack = []
74-
id_campaign = uuid4()
74+
id_campaign = str(uuid4())
75+
76+
# bragg data
77+
with open(DATA_PATH) as f:
78+
for line in f:
79+
filepath = line.strip()
80+
with open(filepath, "rb") as file:
81+
msg = FileType(
82+
filename=os.path.basename(filepath),
83+
file=base64.b64encode(file.read()),
84+
)
85+
# wait 5 seconds for each message
86+
self.message_stack.append(
87+
(
88+
IntersectDirectMessageParams(
89+
destination="nsdf.cloud.diffraction.dashboard.dashboard-service",
90+
operation="NSDFDashboard.get_bragg_data",
91+
payload=msg,
92+
),
93+
2.0,
94+
)
95+
)
7596
for i in range(len(transition_data)):
7697
data = transition_data[i]
7798
nextpoint = (
@@ -87,7 +108,7 @@ def __init__(self) -> None:
87108
destination="nsdf.cloud.diffraction.dashboard.dashboard-service",
88109
operation="NSDFDashboard.get_transition_data_single",
89110
payload=TransitionData(
90-
id=str(id_campaign),
111+
id=id_campaign,
91112
temp=data[0],
92113
ylist=data[1:],
93114
),
@@ -102,35 +123,27 @@ def __init__(self) -> None:
102123
destination="nsdf.cloud.diffraction.dashboard.dashboard-service",
103124
operation="NSDFDashboard.get_next_temperature",
104125
payload=NextTemperature(
105-
id=str(id_campaign),
126+
id=id_campaign,
106127
data=nextpoint,
107128
timestamp=int(time.time()),
108129
),
109130
),
110131
2.0,
111132
)
112133
)
113-
114-
# bragg data
115-
with open(DATA_PATH) as f:
116-
for line in f:
117-
filepath = line.strip()
118-
with open(filepath, "rb") as file:
119-
msg = FileType(
120-
filename=os.path.basename(filepath),
121-
file=base64.b64encode(file.read()),
122-
)
123-
# wait 5 seconds for each message
124-
self.message_stack.append(
125-
(
126-
IntersectDirectMessageParams(
127-
destination="nsdf.cloud.diffraction.dashboard.dashboard-service",
128-
operation="NSDFDashboard.get_bragg_data",
129-
payload=msg,
130-
),
131-
2.0,
132-
)
133-
)
134+
# finish campaign
135+
self.message_stack.append(
136+
(
137+
IntersectDirectMessageParams(
138+
destination="nsdf.cloud.diffraction.dashboard.dashboard-service",
139+
operation="NSDFDashboard.finish_campaign",
140+
payload=FinishCampaignMsg(
141+
id=id_campaign,
142+
),
143+
),
144+
2.0,
145+
)
146+
)
134147
self.message_stack.reverse()
135148

136149
def client_callback(

clients/schema.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,14 @@ class NextTemperature(BaseModel):
4747
id: str
4848
data: float
4949
timestamp: int
50+
51+
52+
class FinishCampaignMsg(BaseModel):
53+
"""
54+
Represents a message to signal the end of a campaign
55+
56+
Attributes:
57+
id(str): The campaign id to finish
58+
"""
59+
60+
id: str

clients/short_list_of_data.txt

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,3 @@
44
./GSAS/NOM168366tof.gsa
55
./GSAS/NOM168367tof.gsa
66
./GSAS/NOM168368tof.gsa
7-
./GSAS/NOM168369tof.gsa
8-
./GSAS/NOM168370tof.gsa
9-
./GSAS/NOM168371tof.gsa
10-
./GSAS/NOM168372tof.gsa
11-
./GSAS/NOM168373tof.gsa
12-
./GSAS/NOM168374tof.gsa
13-
./GSAS/NOM168375tof.gsa
14-
./GSAS/NOM168376tof.gsa
15-
./GSAS/NOM168377tof.gsa
16-
./GSAS/NOM168378tof.gsa
17-
./GSAS/NOM168379tof.gsa
18-
./GSAS/NOM168380tof.gsa
19-
./GSAS/NOM168381tof.gsa
20-
./GSAS/NOM168382tof.gsa
21-
./GSAS/NOM168383tof.gsa
22-
./GSAS/NOM168384tof.gsa
23-
./GSAS/NOM168385tof.gsa
24-
./GSAS/NOM168386tof.gsa
25-
./GSAS/NOM168387tof.gsa
26-
./GSAS/NOM168388tof.gsa
27-
./GSAS/NOM168389tof.gsa
28-
./GSAS/NOM168390tof.gsa
29-
./GSAS/NOM168391tof.gsa
30-
./GSAS/NOM168392tof.gsa
31-
./GSAS/NOM168393tof.gsa
32-
./GSAS/NOM168394tof.gsa
33-
./GSAS/NOM168395tof.gsa
34-
./GSAS/NOM168396tof.gsa
35-
./GSAS/NOM168397tof.gsa
36-
./GSAS/NOM168398tof.gsa

clients/transition_client.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
default_intersect_lifecycle_loop,
2424
)
2525

26-
from schema import TransitionData, NextTemperature
26+
from schema import TransitionData, NextTemperature, FinishCampaignMsg
2727

2828
logging.basicConfig(level=logging.INFO)
2929

@@ -145,6 +145,19 @@ def generate_campaign(
145145
campaign.append(generate_transition_msg(id, temps[i], ylen))
146146
campaign.append(generate_next_temp_msg(id, next_temp))
147147

148+
campaign.append(
149+
(
150+
IntersectDirectMessageParams(
151+
destination="nsdf.cloud.diffraction.dashboard.dashboard-service",
152+
operation="NSDFDashboard.finish_campaign",
153+
payload=FinishCampaignMsg(
154+
id=id,
155+
),
156+
),
157+
2.0,
158+
)
159+
)
160+
148161
return campaign
149162

150163

compose.yaml

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
# Simple docker-compose file which sets up the broker, dashboard, and dashboard service
1+
# Simple docker-compose file which sets up the broker, dashboard, dashboard service, and storage service
22
# Note that for the broker, the default credentials are ` intersect_username / intersect_password `
33

44
services:
55
broker:
66
image: "bitnami/rabbitmq:3.13.3"
7+
container_name: rabbitmq
78
ports:
89
- "1883:1883" # MQTT port
910
- "5672:5672" # AMQP port
@@ -24,47 +25,52 @@ services:
2425

2526
dashboard:
2627
image: "ghcr.io/nsdf-fabric/intersect-dashboard:latest"
28+
container_name: dashboard
2729
ports:
2830
- "10042:10042"
2931
depends_on:
3032
- broker
3133
environment:
3234
BOKEH_ALLOW_WS_ORIGIN: "*"
35+
INTERSECT_DASHBOARD_CONFIG: "/app/config_dashboard_default.yaml"
3336
healthcheck:
3437
test: ["CMD", "curl", "-f", "http://localhost:10042/"]
3538
interval: 10s
3639
retries: 5
3740
start_period: 10s
3841
timeout: 10s
3942
volumes:
40-
- intersect_bragg_data:/usr/src/dashboard/bragg_data/
41-
- intersect_transition_data:/usr/src/dashboard/transition_data/
42-
- intersect_next_temperature_data:/usr/src/dashboard/next_temperature_data/
43+
- intersect_bragg_volume:/usr/src/dashboard/bragg_volume/
44+
- intersect_transition_volume:/usr/src/dashboard/transition_volume/
45+
- intersect_andie_volume:/usr/src/dashboard/andie_volume/
4346
- intersect_scientist_cloud_volume:/usr/src/dashboard/scientist_cloud_volume
4447
dashboard_service:
4548
image: "ghcr.io/nsdf-fabric/intersect-service:latest"
49+
container_name: dashboard_service
4650
ports:
4751
- "10043:10043"
52+
environment:
53+
INTERSECT_SERVICE_CONFIG: "/app/config_default.yaml"
4854
depends_on:
4955
broker:
5056
condition: service_healthy
5157
volumes:
52-
- intersect_bragg_data:/usr/src/dashboard_service/bragg_data/
53-
- intersect_transition_data:/usr/src/dashboard_service/transition_data/
54-
- intersect_next_temperature_data:/usr/src/dashboard_service/next_temperature_data/
58+
- intersect_bragg_volume:/usr/src/dashboard_service/bragg_volume/
59+
- intersect_transition_volume:/usr/src/dashboard_service/transition_volume/
60+
- intersect_andie_volume:/usr/src/dashboard_service/andie_volume/
5561
- intersect_scientist_cloud_volume:/usr/src/dashboard_service/scientist_cloud_volume
5662
storage_service:
5763
image: "ghcr.io/nsdf-fabric/intersect-storage:latest"
58-
env_file:
59-
- .env
64+
container_name: storage_service
6065
ports:
6166
- "10044:10044"
67+
environment:
68+
INTERSECT_SERVICE_CONFIG: "/app/config_storage.yaml"
69+
env_file: ".env"
6270
volumes:
6371
- intersect_scientist_cloud_volume:/usr/src/storage_service/scientist_cloud_volume
64-
- intersect_retry_volume:/usr/src/storage_service/retry_volume
6572
volumes:
66-
intersect_bragg_data:
67-
intersect_transition_data:
68-
intersect_next_temperature_data:
73+
intersect_bragg_volume:
74+
intersect_transition_volume:
75+
intersect_andie_volume:
6976
intersect_scientist_cloud_volume:
70-
intersect_retry_volume:

config/config_storage.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
volumes:
2+
scientist_cloud_volume: "scientist_cloud_volume"
3+
scan_period: 30
4+
sci_cloud:
5+
bucket_prefix: "utk"
6+
bragg_prefix: "bragg"
7+
transition_prefix: "transition"
8+
andie_prefix: "andie"

services/constants.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
NEXT_TEMPERATURE_DATA_PATH = "andie_data"
2424

2525
# DASHBOARD
26-
MAX_BANKS = 6
2726
INTERSECT_DASHBOARD_CONFIG = "INTERSECT_DASHBOARD_CONFIG" # env variable holds the path to dashboard file configuration
28-
2927
# SERVICE
3028
INTERSECT_SERVICE_CONFIG = "INTERSECT_SERVICE_CONFIG" # env variable holds the path to service file configuration
29+
# STORAGE
30+
INTERSECT_STORAGE_CONFIG = "INTERSECT_STORAGE_CONFIG" # env variable holds the path to the storage file configuration

services/dashboard.py

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@
1616
import numpy as np
1717
import yaml
1818
from gsa_loader import load_gsa_file
19-
from constants import (
20-
MAX_BANKS,
21-
INTERSECT_DASHBOARD_CONFIG
22-
)
19+
from constants import INTERSECT_DASHBOARD_CONFIG
2320

2421

2522
logger = logging.getLogger(__name__)
@@ -54,22 +51,11 @@ def __init__(self):
5451
self.bragg_data_dict = dict(
5552
data=[],
5653
layout=go.Layout(
57-
title=dict(text="Bragg Data", font=dict(size=22, weight="bold")),
58-
xaxis=dict(title=dict(text="d-Spacing", font=dict(size=16)), tickfont=dict(size=14)),
59-
yaxis=dict(title=dict(text="Intensity", font=dict(size=16)), tickfont=dict(size=14)),
54+
title=dict(text="Bragg Data", font=dict(size=26, weight="bold")),
55+
xaxis=dict(title=dict(text="d-Spacing", font=dict(size=22)), tickfont=dict(size=18)),
56+
yaxis=dict(title=dict(text="Intensity", font=dict(size=22)), tickfont=dict(size=18)),
6057
),
6158
)
62-
self.bragg_data_by_bank_dict = [
63-
dict(
64-
data=[],
65-
layout=go.Layout(
66-
title=dict(text=f"Bank {i+1}", font=dict(size=22, weight="bold")),
67-
xaxis=dict(title=dict(text="d-Spacing", font=dict(size=16)), tickfont=dict(size=14)),
68-
yaxis=dict(title=dict(text="Intensity", font=dict(size=16)), tickfont=dict(size=14)),
69-
),
70-
)
71-
for i in range(MAX_BANKS)
72-
]
7359
self.transition_data_dict = dict(
7460
data=[
7561
go.Scatter(
@@ -81,20 +67,20 @@ def __init__(self):
8167
)
8268
],
8369
layout=go.Layout(
84-
title=dict(text="Transition Plot", font=dict(size=22, weight="bold")),
85-
xaxis=dict(title=dict(text="Temperature (K)", font=dict(size=16)), tickfont=dict(size=14)),
86-
yaxis=dict(title=dict(text="d-Spacing", font=dict(size=16)), tickfont=dict(size=14)),
87-
legend=dict(font=dict(size=16))
70+
title=dict(text="Transition Plot", font=dict(size=26, weight="bold")),
71+
xaxis=dict(title=dict(text="Temperature (K)", font=dict(size=22)), tickfont=dict(size=18)),
72+
yaxis=dict(title=dict(text="d-Spacing", font=dict(size=22)), tickfont=dict(size=18)),
73+
legend=dict(font=dict(size=22))
8874
),
8975
)
9076
self.stateful_plot_data_dict = dict(
9177
data=[],
9278
layout=go.Layout(
9379
title=dict(
94-
text="Bragg Data Stateful Plot", font=dict(size=22, weight="bold")
80+
text="Bragg Data Stateful Plot", font=dict(size=26, weight="bold")
9581
),
96-
xaxis=dict(title=dict(text="d-Spacing", font=dict(size=16)), tickfont=dict(size=14)),
97-
yaxis=dict(title=dict(text="Intensity", font=dict(size=16)), tickfont=dict(size=14)),
82+
xaxis=dict(title=dict(text="d-Spacing", font=dict(size=22)), tickfont=dict(size=18)),
83+
yaxis=dict(title=dict(text="Intensity", font=dict(size=22)), tickfont=dict(size=18)),
9884

9985
),
10086
)
@@ -116,7 +102,7 @@ def __init__(self):
116102

117103
self.by_bank_tab = pn.Column(
118104
pn.pane.Markdown("<h1>By Bank</h1>"),
119-
pn.GridBox(*self.bragg_data_by_bank_plots, ncols=3))
105+
pn.FlexBox(*self.bragg_data_by_bank_plots))
120106

121107
self.select_bragg_file = pn.widgets.AutocompleteInput(
122108
name="Bragg File Timestamp",
@@ -296,10 +282,10 @@ def _render_bragg_plot(self):
296282
pn.pane.Plotly(dict(
297283
data=scatter_line,
298284
layout=go.Layout(
299-
title=dict(text=f"Bank {wksp_index}", font=dict(size=22, weight="bold")),
300-
xaxis=dict(title="d-Spacing"),
301-
yaxis=dict(title="Intensity"))
302-
)))
285+
title=dict(text=f"Bank {wksp_index}", font=dict(size=26, weight="bold")),
286+
xaxis=dict(title=dict(text="d-Spacing", font=dict(size=22)), tickfont=dict(size=18)),
287+
yaxis=dict(title=dict(text="Intensity", font=dict(size=22)), tickfont=dict(size=18)),)
288+
), sizing_mode="stretch_both"))
303289

304290
traces.append(scatter_line)
305291

@@ -584,7 +570,7 @@ def App() -> MaterialTemplate:
584570
)
585571
pn.state.add_periodic_callback(
586572
callback=app_state.poll_transition_and_andie,
587-
period=app_state.config['scan_period']['transition_scan_period'] * 1000,
573+
period=app_state.config['scan_period']['transition_scan_period'] * 1000,
588574
)
589575

590576
pn.state.add_periodic_callback(

0 commit comments

Comments
 (0)