flowcept 0.8.3__py3-none-any.whl → 0.8.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flowcept/commons/autoflush_buffer.py +4 -3
- flowcept/commons/daos/mq_dao/mq_dao_base.py +31 -7
- flowcept/commons/daos/mq_dao/mq_dao_kafka.py +24 -9
- flowcept/commons/daos/mq_dao/mq_dao_mofka.py +26 -6
- flowcept/commons/daos/mq_dao/mq_dao_redis.py +27 -10
- flowcept/configs.py +4 -4
- flowcept/flowceptor/adapters/dask/dask_interceptor.py +5 -28
- flowcept/flowceptor/adapters/dask/dask_plugins.py +20 -32
- flowcept/flowceptor/consumers/document_inserter.py +2 -2
- flowcept/version.py +1 -1
- {flowcept-0.8.3.dist-info → flowcept-0.8.4.dist-info}/METADATA +1 -1
- {flowcept-0.8.3.dist-info → flowcept-0.8.4.dist-info}/RECORD +15 -15
- resources/sample_settings.yaml +1 -0
- {flowcept-0.8.3.dist-info → flowcept-0.8.4.dist-info}/WHEEL +0 -0
- {flowcept-0.8.3.dist-info → flowcept-0.8.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -9,13 +9,14 @@ class AutoflushBuffer:
|
|
|
9
9
|
|
|
10
10
|
def __init__(
|
|
11
11
|
self,
|
|
12
|
-
max_size,
|
|
13
|
-
flush_interval,
|
|
14
12
|
flush_function: Callable,
|
|
13
|
+
max_size=None,
|
|
14
|
+
flush_interval=None,
|
|
15
15
|
flush_function_args=[],
|
|
16
16
|
flush_function_kwargs={},
|
|
17
17
|
):
|
|
18
|
-
self._max_size = max_size
|
|
18
|
+
self._max_size = max_size or float("inf")
|
|
19
|
+
self._flush_interval = flush_interval or float("inf")
|
|
19
20
|
self._flush_interval = flush_interval
|
|
20
21
|
self._buffers = [[], []]
|
|
21
22
|
self._current_buffer_index = 0
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
4
|
from typing import Union, List, Callable
|
|
5
|
-
|
|
5
|
+
import csv
|
|
6
6
|
import msgpack
|
|
7
|
-
|
|
7
|
+
from time import time
|
|
8
8
|
import flowcept.commons
|
|
9
9
|
from flowcept.commons.autoflush_buffer import AutoflushBuffer
|
|
10
10
|
|
|
@@ -19,6 +19,7 @@ from flowcept.configs import (
|
|
|
19
19
|
MQ_INSERTION_BUFFER_TIME,
|
|
20
20
|
MQ_CHUNK_SIZE,
|
|
21
21
|
MQ_TYPE,
|
|
22
|
+
MQ_TIMING,
|
|
22
23
|
)
|
|
23
24
|
|
|
24
25
|
from flowcept.commons.utils import GenericJSONEncoder
|
|
@@ -69,12 +70,21 @@ class MQDao(ABC):
|
|
|
69
70
|
self._keyvalue_dao = KeyValueDAO()
|
|
70
71
|
self._time_based_flushing_started = False
|
|
71
72
|
self.buffer: Union[AutoflushBuffer, List] = None
|
|
72
|
-
|
|
73
|
+
if MQ_TIMING:
|
|
74
|
+
self._flush_events = []
|
|
75
|
+
self.stop = self._stop_timed
|
|
76
|
+
self.send_message = self._send_message_timed
|
|
77
|
+
self._bulk_publish = self._bulk_publish_timed
|
|
78
|
+
else:
|
|
79
|
+
self.stop = self._stop
|
|
73
80
|
|
|
74
81
|
@abstractmethod
|
|
75
82
|
def _bulk_publish(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
76
83
|
raise NotImplementedError()
|
|
77
84
|
|
|
85
|
+
def _bulk_publish_timed(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
86
|
+
raise NotImplementedError()
|
|
87
|
+
|
|
78
88
|
def bulk_publish(self, buffer):
|
|
79
89
|
"""Publish it."""
|
|
80
90
|
# self.logger.info(f"Going to flush {len(buffer)} to MQ...")
|
|
@@ -132,12 +142,10 @@ class MQDao(ABC):
|
|
|
132
142
|
"""Create the buffer."""
|
|
133
143
|
if not self.started:
|
|
134
144
|
if flowcept.configs.DB_FLUSH_MODE == "online":
|
|
135
|
-
# msg = "Starting MQ time-based flushing! bundle: "
|
|
136
|
-
# self.logger.debug(msg+f"{exec_bundle_id}; interceptor id: {interceptor_instance_id}")
|
|
137
145
|
self.buffer = AutoflushBuffer(
|
|
146
|
+
flush_function=self.bulk_publish,
|
|
138
147
|
max_size=MQ_BUFFER_SIZE,
|
|
139
148
|
flush_interval=MQ_INSERTION_BUFFER_TIME,
|
|
140
|
-
flush_function=self.bulk_publish,
|
|
141
149
|
)
|
|
142
150
|
self.register_time_based_thread_init(interceptor_instance_id, exec_bundle_id)
|
|
143
151
|
self._time_based_flushing_started = True
|
|
@@ -156,7 +164,18 @@ class MQDao(ABC):
|
|
|
156
164
|
self.bulk_publish(self.buffer)
|
|
157
165
|
self.buffer = list()
|
|
158
166
|
|
|
159
|
-
def
|
|
167
|
+
def _stop_timed(self, interceptor_instance_id: str, bundle_exec_id: int = None):
|
|
168
|
+
t1 = time()
|
|
169
|
+
self._stop(interceptor_instance_id, bundle_exec_id)
|
|
170
|
+
t2 = time()
|
|
171
|
+
self._flush_events.append(["final", t1, t2, t2 - t1, "n/a"])
|
|
172
|
+
|
|
173
|
+
with open(f"{MQ_TYPE}_{interceptor_instance_id}_{MQ_TYPE}_flush_events.csv", "w", newline="") as file:
|
|
174
|
+
writer = csv.writer(file)
|
|
175
|
+
writer.writerow(["type", "start", "end", "duration", "size"])
|
|
176
|
+
writer.writerows(self._flush_events)
|
|
177
|
+
|
|
178
|
+
def _stop(self, interceptor_instance_id: str, bundle_exec_id: int = None):
|
|
160
179
|
"""Stop it."""
|
|
161
180
|
msg0 = "MQ publisher received stop signal! bundle: "
|
|
162
181
|
self.logger.debug(msg0 + f"{bundle_exec_id}; interceptor id: {interceptor_instance_id}")
|
|
@@ -189,6 +208,11 @@ class MQDao(ABC):
|
|
|
189
208
|
"""Send a message."""
|
|
190
209
|
raise NotImplementedError()
|
|
191
210
|
|
|
211
|
+
@abstractmethod
|
|
212
|
+
def _send_message_timed(self, message: dict, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
213
|
+
"""Send a message."""
|
|
214
|
+
raise NotImplementedError()
|
|
215
|
+
|
|
192
216
|
@abstractmethod
|
|
193
217
|
def message_listener(self, message_handler: Callable):
|
|
194
218
|
"""Get message listener."""
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
"""MQ kafka module."""
|
|
2
2
|
|
|
3
3
|
from typing import Callable
|
|
4
|
-
|
|
5
|
-
import msgpack
|
|
6
4
|
from time import time
|
|
5
|
+
import msgpack
|
|
7
6
|
|
|
8
7
|
from confluent_kafka import Producer, Consumer, KafkaError
|
|
9
8
|
from confluent_kafka.admin import AdminClient
|
|
10
9
|
|
|
11
10
|
from flowcept.commons.daos.mq_dao.mq_dao_base import MQDao
|
|
12
|
-
from flowcept.commons.utils import perf_log
|
|
13
11
|
from flowcept.configs import (
|
|
14
12
|
MQ_CHANNEL,
|
|
15
|
-
PERF_LOG,
|
|
16
13
|
MQ_HOST,
|
|
17
14
|
MQ_PORT,
|
|
18
15
|
)
|
|
@@ -69,26 +66,44 @@ class MQDaoKafka(MQDao):
|
|
|
69
66
|
self._producer.produce(channel, key=channel, value=serializer(message))
|
|
70
67
|
self._producer.flush()
|
|
71
68
|
|
|
69
|
+
def _send_message_timed(self, message: dict, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
70
|
+
t1 = time()
|
|
71
|
+
self.send_message(message, channel, serializer)
|
|
72
|
+
t2 = time()
|
|
73
|
+
self._flush_events.append(["single", t1, t2, t2 - t1, len(str(message).encode())])
|
|
74
|
+
|
|
72
75
|
def _bulk_publish(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
76
|
+
for message in buffer:
|
|
77
|
+
try:
|
|
78
|
+
self._producer.produce(channel, key=channel, value=serializer(message))
|
|
79
|
+
except Exception as e:
|
|
80
|
+
self.logger.exception(e)
|
|
81
|
+
self.logger.error("Some messages couldn't be flushed! Check the messages' contents!")
|
|
82
|
+
self.logger.error(f"Message that caused error: {message}")
|
|
83
|
+
try:
|
|
84
|
+
self._producer.flush()
|
|
85
|
+
self.logger.info(f"Flushed {len(buffer)} msgs to MQ!")
|
|
86
|
+
except Exception as e:
|
|
87
|
+
self.logger.exception(e)
|
|
88
|
+
|
|
89
|
+
def _bulk_publish_timed(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
73
90
|
total = 0
|
|
74
91
|
for message in buffer:
|
|
75
92
|
try:
|
|
76
|
-
self.logger.debug(f"Going to send Message:\n\t[BEGIN_MSG]{message}\n[END_MSG]\t")
|
|
77
93
|
self._producer.produce(channel, key=channel, value=serializer(message))
|
|
78
94
|
total += len(str(message).encode())
|
|
79
95
|
except Exception as e:
|
|
80
96
|
self.logger.exception(e)
|
|
81
97
|
self.logger.error("Some messages couldn't be flushed! Check the messages' contents!")
|
|
82
98
|
self.logger.error(f"Message that caused error: {message}")
|
|
83
|
-
t0 = 0
|
|
84
|
-
if PERF_LOG:
|
|
85
|
-
t0 = time()
|
|
86
99
|
try:
|
|
100
|
+
t1 = time()
|
|
87
101
|
self._producer.flush()
|
|
102
|
+
t2 = time()
|
|
103
|
+
self._flush_events.append(["bulk", t1, t2, t2 - t1, total])
|
|
88
104
|
self.logger.info(f"Flushed {len(buffer)} msgs to MQ!")
|
|
89
105
|
except Exception as e:
|
|
90
106
|
self.logger.exception(e)
|
|
91
|
-
perf_log("mq_pipe_flush", t0)
|
|
92
107
|
|
|
93
108
|
def liveness_test(self):
|
|
94
109
|
"""Get the livelyness of it."""
|
|
@@ -9,8 +9,7 @@ import mochi.mofka.client as mofka
|
|
|
9
9
|
from mochi.mofka.client import ThreadPool, AdaptiveBatchSize
|
|
10
10
|
|
|
11
11
|
from flowcept.commons.daos.mq_dao.mq_dao_base import MQDao
|
|
12
|
-
from flowcept.
|
|
13
|
-
from flowcept.configs import PERF_LOG, MQ_SETTINGS, MQ_CHANNEL
|
|
12
|
+
from flowcept.configs import MQ_SETTINGS, MQ_CHANNEL
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
class MQDaoMofka(MQDao):
|
|
@@ -58,7 +57,29 @@ class MQDaoMofka(MQDao):
|
|
|
58
57
|
self.producer.push(metadata=message) # using metadata to send data
|
|
59
58
|
self.producer.flush()
|
|
60
59
|
|
|
60
|
+
def _send_message_timed(self, message: dict, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
61
|
+
t1 = time()
|
|
62
|
+
self.send_message(message, channel, serializer)
|
|
63
|
+
t2 = time()
|
|
64
|
+
self._flush_events.append(["single", t1, t2, t2 - t1, len(str(message).encode())])
|
|
65
|
+
|
|
61
66
|
def _bulk_publish(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
67
|
+
try:
|
|
68
|
+
self.logger.debug(f"Going to send Message:\n\t[BEGIN_MSG]{buffer}\n[END_MSG]\t")
|
|
69
|
+
for m in buffer:
|
|
70
|
+
self.producer.push(m)
|
|
71
|
+
|
|
72
|
+
except Exception as e:
|
|
73
|
+
self.logger.exception(e)
|
|
74
|
+
self.logger.error("Some messages couldn't be flushed! Check the messages' contents!")
|
|
75
|
+
self.logger.error(f"Message that caused error: {buffer}")
|
|
76
|
+
try:
|
|
77
|
+
self.producer.flush()
|
|
78
|
+
self.logger.info(f"Flushed {len(buffer)} msgs to MQ!")
|
|
79
|
+
except Exception as e:
|
|
80
|
+
self.logger.exception(e)
|
|
81
|
+
|
|
82
|
+
def _bulk_publish_timed(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
62
83
|
total = 0
|
|
63
84
|
try:
|
|
64
85
|
self.logger.debug(f"Going to send Message:\n\t[BEGIN_MSG]{buffer}\n[END_MSG]\t")
|
|
@@ -71,15 +92,14 @@ class MQDaoMofka(MQDao):
|
|
|
71
92
|
self.logger.exception(e)
|
|
72
93
|
self.logger.error("Some messages couldn't be flushed! Check the messages' contents!")
|
|
73
94
|
self.logger.error(f"Message that caused error: {buffer}")
|
|
74
|
-
t0 = 0
|
|
75
|
-
if PERF_LOG:
|
|
76
|
-
t0 = time()
|
|
77
95
|
try:
|
|
96
|
+
t1 = time()
|
|
78
97
|
self.producer.flush()
|
|
98
|
+
t2 = time()
|
|
99
|
+
self._flush_events.append(["bulk", t1, t2, t2 - t1, total])
|
|
79
100
|
self.logger.info(f"Flushed {len(buffer)} msgs to MQ!")
|
|
80
101
|
except Exception as e:
|
|
81
102
|
self.logger.exception(e)
|
|
82
|
-
perf_log("mq_pipe_flush", t0)
|
|
83
103
|
|
|
84
104
|
def liveness_test(self):
|
|
85
105
|
"""Test Mofka Liveness."""
|
|
@@ -7,11 +7,7 @@ import msgpack
|
|
|
7
7
|
from time import time, sleep
|
|
8
8
|
|
|
9
9
|
from flowcept.commons.daos.mq_dao.mq_dao_base import MQDao
|
|
10
|
-
from flowcept.
|
|
11
|
-
from flowcept.configs import (
|
|
12
|
-
MQ_CHANNEL,
|
|
13
|
-
PERF_LOG,
|
|
14
|
-
)
|
|
10
|
+
from flowcept.configs import MQ_CHANNEL
|
|
15
11
|
|
|
16
12
|
|
|
17
13
|
class MQDaoRedis(MQDao):
|
|
@@ -62,26 +58,47 @@ class MQDaoRedis(MQDao):
|
|
|
62
58
|
"""Send the message."""
|
|
63
59
|
self._producer.publish(channel, serializer(message))
|
|
64
60
|
|
|
61
|
+
def _send_message_timed(self, message: dict, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
62
|
+
"""Send the message using timing for performance evaluation."""
|
|
63
|
+
t1 = time()
|
|
64
|
+
self.send_message(message, channel, serializer)
|
|
65
|
+
t2 = time()
|
|
66
|
+
self._flush_events.append(["single", t1, t2, t2 - t1, len(str(message).encode())])
|
|
67
|
+
|
|
65
68
|
def _bulk_publish(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
69
|
+
pipe = self._producer.pipeline()
|
|
70
|
+
for message in buffer:
|
|
71
|
+
try:
|
|
72
|
+
pipe.publish(channel, serializer(message))
|
|
73
|
+
except Exception as e:
|
|
74
|
+
self.logger.exception(e)
|
|
75
|
+
self.logger.error("Some messages couldn't be flushed! Check the messages' contents!")
|
|
76
|
+
self.logger.error(f"Message that caused error: {message}")
|
|
77
|
+
try:
|
|
78
|
+
pipe.execute()
|
|
79
|
+
self.logger.debug(f"Flushed {len(buffer)} msgs to MQ!")
|
|
80
|
+
except Exception as e:
|
|
81
|
+
self.logger.exception(e)
|
|
82
|
+
|
|
83
|
+
def _bulk_publish_timed(self, buffer, channel=MQ_CHANNEL, serializer=msgpack.dumps):
|
|
66
84
|
total = 0
|
|
67
85
|
pipe = self._producer.pipeline()
|
|
68
86
|
for message in buffer:
|
|
69
87
|
try:
|
|
70
88
|
total += len(str(message).encode())
|
|
71
|
-
pipe.publish(
|
|
89
|
+
pipe.publish(channel, serializer(message))
|
|
72
90
|
except Exception as e:
|
|
73
91
|
self.logger.exception(e)
|
|
74
92
|
self.logger.error("Some messages couldn't be flushed! Check the messages' contents!")
|
|
75
93
|
self.logger.error(f"Message that caused error: {message}")
|
|
76
|
-
t0 = 0
|
|
77
|
-
if PERF_LOG:
|
|
78
|
-
t0 = time()
|
|
79
94
|
try:
|
|
95
|
+
t1 = time()
|
|
80
96
|
pipe.execute()
|
|
97
|
+
t2 = time()
|
|
98
|
+
self._flush_events.append(["bulk", t1, t2, t2 - t1, total])
|
|
81
99
|
self.logger.debug(f"Flushed {len(buffer)} msgs to MQ!")
|
|
82
100
|
except Exception as e:
|
|
83
101
|
self.logger.exception(e)
|
|
84
|
-
perf_log("mq_pipe_execute", t0)
|
|
85
102
|
|
|
86
103
|
def liveness_test(self):
|
|
87
104
|
"""Get the livelyness of it."""
|
flowcept/configs.py
CHANGED
|
@@ -73,9 +73,9 @@ MQ_CHANNEL = settings["mq"].get("channel", "interception")
|
|
|
73
73
|
MQ_PASSWORD = settings["mq"].get("password", None)
|
|
74
74
|
MQ_HOST = os.getenv("MQ_HOST", settings["mq"].get("host", "localhost"))
|
|
75
75
|
MQ_PORT = int(os.getenv("MQ_PORT", settings["mq"].get("port", "6379")))
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
MQ_BUFFER_SIZE = settings["mq"].get("buffer_size", None)
|
|
77
|
+
MQ_INSERTION_BUFFER_TIME = settings["mq"].get("insertion_buffer_time_secs", None)
|
|
78
|
+
MQ_TIMING = settings["mq"].get("timing", False)
|
|
79
79
|
MQ_CHUNK_SIZE = int(settings["mq"].get("chunk_size", -1))
|
|
80
80
|
|
|
81
81
|
#####################
|
|
@@ -127,7 +127,7 @@ if not LMDB_ENABLED and not MONGO_ENABLED:
|
|
|
127
127
|
##########################
|
|
128
128
|
db_buffer_settings = settings["db_buffer"]
|
|
129
129
|
# In seconds:
|
|
130
|
-
INSERTION_BUFFER_TIME =
|
|
130
|
+
INSERTION_BUFFER_TIME = db_buffer_settings.get("insertion_buffer_time_secs", None)
|
|
131
131
|
ADAPTIVE_DB_BUFFER_SIZE = db_buffer_settings.get("adaptive_buffer_size", True)
|
|
132
132
|
DB_MAX_BUFFER_SIZE = int(db_buffer_settings.get("max_buffer_size", 50))
|
|
133
133
|
DB_MIN_BUFFER_SIZE = max(1, int(db_buffer_settings.get("min_buffer_size", 10)))
|
|
@@ -21,32 +21,6 @@ from flowcept.flowceptor.adapters.instrumentation_interceptor import Instrumenta
|
|
|
21
21
|
|
|
22
22
|
def get_run_spec_data(task_msg: TaskObject, run_spec):
|
|
23
23
|
"""Get the run specs."""
|
|
24
|
-
# def _get_arg(arg_name):
|
|
25
|
-
# if type(run_spec) == dict:
|
|
26
|
-
# return run_spec.get(arg_name, None)
|
|
27
|
-
# elif hasattr(run_spec, arg_name):
|
|
28
|
-
# return getattr(run_spec, arg_name)
|
|
29
|
-
# return None
|
|
30
|
-
#
|
|
31
|
-
# def _parse_dask_tuple(_tuple: tuple):
|
|
32
|
-
# forth_elem = None
|
|
33
|
-
# if len(_tuple) == 3:
|
|
34
|
-
# _, _, value_tuple = _tuple
|
|
35
|
-
# elif len(_tuple) == 4:
|
|
36
|
-
# _, _, value_tuple, forth_elem = _tuple
|
|
37
|
-
#
|
|
38
|
-
# _, value = value_tuple
|
|
39
|
-
# if len(value) == 1: # Value is always an array here
|
|
40
|
-
# value = value[0]
|
|
41
|
-
# ret_obj = {"value": value}
|
|
42
|
-
#
|
|
43
|
-
# if forth_elem is not None and type(forth_elem) == dict:
|
|
44
|
-
# ret_obj.update(forth_elem)
|
|
45
|
-
# else:
|
|
46
|
-
# pass # We don't know yet what to do if this happens. So just pass.
|
|
47
|
-
#
|
|
48
|
-
# return ret_obj
|
|
49
|
-
|
|
50
24
|
func = run_spec[0]
|
|
51
25
|
task_msg.activity_id = func.__name__
|
|
52
26
|
args = run_spec[1]
|
|
@@ -91,7 +65,7 @@ class DaskWorkerInterceptor(BaseInterceptor):
|
|
|
91
65
|
self._plugin_key = plugin_key
|
|
92
66
|
self._worker = None
|
|
93
67
|
self.kind = kind
|
|
94
|
-
# super().__init__ goes to setup_worker.
|
|
68
|
+
# super().__init__ goes to setup_worker. I'm leaving this commented here as a reminder.
|
|
95
69
|
|
|
96
70
|
def setup_worker(self, worker):
|
|
97
71
|
"""Set the worker.
|
|
@@ -101,7 +75,8 @@ class DaskWorkerInterceptor(BaseInterceptor):
|
|
|
101
75
|
"""
|
|
102
76
|
self._worker = worker
|
|
103
77
|
super().__init__(plugin_key=self._plugin_key, kind=self.kind)
|
|
104
|
-
|
|
78
|
+
self._worker.flowcept_tasks = {}
|
|
79
|
+
# TODO: :refactor: Below is just to avoid the auto-generation of workflow id, which doesn't make sense in Dask.
|
|
105
80
|
self._generated_workflow_id = True
|
|
106
81
|
super().start(bundle_exec_id=self._worker.scheduler.address)
|
|
107
82
|
|
|
@@ -129,6 +104,8 @@ class DaskWorkerInterceptor(BaseInterceptor):
|
|
|
129
104
|
task_msg.address = self._worker.worker_address
|
|
130
105
|
if self.settings.worker_create_timestamps:
|
|
131
106
|
task_msg.started_at = get_utc_now()
|
|
107
|
+
|
|
108
|
+
self._worker.flowcept_tasks[task_id] = task_msg
|
|
132
109
|
elif ts.state == "memory":
|
|
133
110
|
task_msg.status = Status.FINISHED
|
|
134
111
|
if self.settings.worker_create_timestamps:
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"""Dask plugin module."""
|
|
2
2
|
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
3
5
|
from distributed import Client, WorkerPlugin
|
|
4
6
|
|
|
5
7
|
from flowcept import WorkflowObject
|
|
8
|
+
from flowcept.commons.flowcept_dataclasses.task_object import TaskObject
|
|
6
9
|
from flowcept.configs import INSTRUMENTATION
|
|
7
10
|
from flowcept.flowceptor.adapters.dask.dask_interceptor import (
|
|
8
11
|
DaskWorkerInterceptor,
|
|
@@ -10,38 +13,6 @@ from flowcept.flowceptor.adapters.dask.dask_interceptor import (
|
|
|
10
13
|
from flowcept.flowceptor.adapters.instrumentation_interceptor import InstrumentationInterceptor
|
|
11
14
|
|
|
12
15
|
|
|
13
|
-
# def _set_workflow_on_scheduler(
|
|
14
|
-
# dask_scheduler=None,
|
|
15
|
-
# workflow_id=None,
|
|
16
|
-
# custom_metadata: dict = None,
|
|
17
|
-
# campaign_id: str = None,
|
|
18
|
-
# workflow_name: str = None,
|
|
19
|
-
# used: dict = None,
|
|
20
|
-
# ):
|
|
21
|
-
# custom_metadata = custom_metadata or {}
|
|
22
|
-
# wf_obj = WorkflowObject()
|
|
23
|
-
# wf_obj.workflow_id = workflow_id
|
|
24
|
-
# custom_metadata.update(
|
|
25
|
-
# {
|
|
26
|
-
# "workflow_type": "DaskWorkflow",
|
|
27
|
-
# "scheduler": dask_scheduler.address_safe,
|
|
28
|
-
# "scheduler_id": dask_scheduler.id,
|
|
29
|
-
# "scheduler_pid": dask_scheduler.proc.pid,
|
|
30
|
-
# "clients": len(dask_scheduler.clients),
|
|
31
|
-
# "n_workers": len(dask_scheduler.workers),
|
|
32
|
-
# }
|
|
33
|
-
# )
|
|
34
|
-
# wf_obj.custom_metadata = custom_metadata
|
|
35
|
-
# wf_obj.used = used
|
|
36
|
-
# wf_obj.campaign_id = campaign_id
|
|
37
|
-
# wf_obj.name = workflow_name
|
|
38
|
-
#
|
|
39
|
-
# interceptor = BaseInterceptor(plugin_key="dask")
|
|
40
|
-
# interceptor.start(bundle_exec_id=dask_scheduler.address)
|
|
41
|
-
# interceptor.send_workflow_message(wf_obj)
|
|
42
|
-
# interceptor.stop()
|
|
43
|
-
|
|
44
|
-
|
|
45
16
|
def _set_workflow_on_workers(dask_worker, workflow_id, campaign_id=None):
|
|
46
17
|
setattr(dask_worker, "current_workflow_id", workflow_id)
|
|
47
18
|
if campaign_id:
|
|
@@ -53,6 +24,23 @@ def set_workflow_info_on_workers(dask_client: Client, wf_obj: WorkflowObject):
|
|
|
53
24
|
dask_client.run(_set_workflow_on_workers, workflow_id=wf_obj.workflow_id, campaign_id=wf_obj.campaign_id)
|
|
54
25
|
|
|
55
26
|
|
|
27
|
+
def get_flowcept_task() -> Optional[TaskObject]:
|
|
28
|
+
"""Get the Flowcept Task Object inside a Worker's task."""
|
|
29
|
+
from distributed import get_worker
|
|
30
|
+
from distributed.worker import thread_state
|
|
31
|
+
|
|
32
|
+
worker = get_worker()
|
|
33
|
+
try:
|
|
34
|
+
task_id = thread_state.key if hasattr(thread_state, "key") else None
|
|
35
|
+
if hasattr(worker, "flowcept_tasks") and task_id in worker.flowcept_tasks:
|
|
36
|
+
return worker.flowcept_tasks[task_id]
|
|
37
|
+
else:
|
|
38
|
+
return None
|
|
39
|
+
except Exception as e:
|
|
40
|
+
print(e)
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
|
|
56
44
|
class FlowceptDaskWorkerAdapter(WorkerPlugin):
|
|
57
45
|
"""Dask worker adapter."""
|
|
58
46
|
|
|
@@ -71,10 +71,10 @@ class DocumentInserter:
|
|
|
71
71
|
self._bundle_exec_id = bundle_exec_id
|
|
72
72
|
self.check_safe_stops = check_safe_stops
|
|
73
73
|
self.buffer: AutoflushBuffer = AutoflushBuffer(
|
|
74
|
-
max_size=self._curr_max_buffer_size,
|
|
75
|
-
flush_interval=INSERTION_BUFFER_TIME,
|
|
76
74
|
flush_function=DocumentInserter.flush_function,
|
|
77
75
|
flush_function_kwargs={"logger": self.logger, "doc_daos": self._doc_daos},
|
|
76
|
+
max_size=self._curr_max_buffer_size,
|
|
77
|
+
flush_interval=INSERTION_BUFFER_TIME,
|
|
78
78
|
)
|
|
79
79
|
|
|
80
80
|
def _set_buffer_size(self):
|
flowcept/version.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
flowcept/__init__.py,sha256=CukmdzTUvm6Y_plTKPq4kKn7w9LdR36j7V_C_UQyjhU,2011
|
|
2
|
-
flowcept/configs.py,sha256=
|
|
3
|
-
flowcept/version.py,sha256=
|
|
2
|
+
flowcept/configs.py,sha256=_-jhoI_HGKjzymjYTlDuysbM38Gr2aunc0Q-Stlmcwk,7511
|
|
3
|
+
flowcept/version.py,sha256=sgsQa7sBlHkp-P60Bs4HRcOzfCc2iDmfQsjJbMii7Xg,306
|
|
4
4
|
flowcept/analytics/__init__.py,sha256=46q-7vsHq_ddPNrzNnDgEOiRgvlx-5Ggu2ocyROMV0w,641
|
|
5
5
|
flowcept/analytics/analytics_utils.py,sha256=FRJdBtQa7Hrk2oR_FFhmhmMf3X6YyZ4nbH5RIYh7KL4,8753
|
|
6
6
|
flowcept/analytics/data_augmentation.py,sha256=Dyr5x316Zf-k1e8rVoQMCpFOrklYVHjfejRPrtoycmc,1641
|
|
7
7
|
flowcept/analytics/plot.py,sha256=L56y1HRnTE6-Fxs62Y0rV2OtDwjSwgSP3yLdalkiRBQ,2932
|
|
8
8
|
flowcept/commons/__init__.py,sha256=W94CqapS0IGuuIGHHaz4sNuuiYhgtJWtpDEbnI0pGwI,26
|
|
9
|
-
flowcept/commons/autoflush_buffer.py,sha256=
|
|
9
|
+
flowcept/commons/autoflush_buffer.py,sha256=8M0fcIeHck-mSGQ2HFpW3_Af8-dHswhIbUMX5FATm48,2589
|
|
10
10
|
flowcept/commons/flowcept_logger.py,sha256=0asRucrDMeRXvsdhuCmH6lWO7lAt_Z5o5uW7rrQhcjc,1857
|
|
11
11
|
flowcept/commons/query_utils.py,sha256=3tyK5VYA10iDtmtzNwa8OQGn93DBxsu6rTjHDphftSc,2208
|
|
12
12
|
flowcept/commons/settings_factory.py,sha256=vpvnpqabPKK-mzoZ5iLdnefpemW1MldDOZhii_m9wNk,1814
|
|
@@ -19,10 +19,10 @@ flowcept/commons/daos/docdb_dao/docdb_dao_base.py,sha256=YbfSVJPwZGK2GBYkeapRC83
|
|
|
19
19
|
flowcept/commons/daos/docdb_dao/lmdb_dao.py,sha256=dJOLgCx_lwdz6MKiMpM_UE4rm0angDCPaVz_WU5KqIA,10407
|
|
20
20
|
flowcept/commons/daos/docdb_dao/mongodb_dao.py,sha256=-Kxjep1FbjKiGjvzyvePVHDf-Q1lOIce1EzBURSKubc,38037
|
|
21
21
|
flowcept/commons/daos/mq_dao/__init__.py,sha256=Xxm4FmbBUZDQ7XIAmSFbeKE_AdHsbgFmSuftvMWSykQ,21
|
|
22
|
-
flowcept/commons/daos/mq_dao/mq_dao_base.py,sha256=
|
|
23
|
-
flowcept/commons/daos/mq_dao/mq_dao_kafka.py,sha256=
|
|
24
|
-
flowcept/commons/daos/mq_dao/mq_dao_mofka.py,sha256=
|
|
25
|
-
flowcept/commons/daos/mq_dao/mq_dao_redis.py,sha256=
|
|
22
|
+
flowcept/commons/daos/mq_dao/mq_dao_base.py,sha256=EAqOhy7Q8V29JFDG8C50nRK34KsPxEICkG4elk4ZfX8,9020
|
|
23
|
+
flowcept/commons/daos/mq_dao/mq_dao_kafka.py,sha256=bf-bZvWw9JJk8Kdfzx2UkAnQC95rSrKXDEyYkrcncOk,4400
|
|
24
|
+
flowcept/commons/daos/mq_dao/mq_dao_mofka.py,sha256=aZ810wN5Wkjk7oRUxDWJWOIREUsmq57oI4AxY1bWBuk,3940
|
|
25
|
+
flowcept/commons/daos/mq_dao/mq_dao_redis.py,sha256=Br97SoDIkt4dHH937Yjg3wtkn1xGT-x9t-8E3VD5TeU,4277
|
|
26
26
|
flowcept/commons/flowcept_dataclasses/__init__.py,sha256=8KkiJh0WSRAB50waVluxCSI8Tb9X1L9nup4c8RN3ulc,30
|
|
27
27
|
flowcept/commons/flowcept_dataclasses/base_settings_dataclasses.py,sha256=Cjw2PGYtZDfnwecz6G3S42Ncmxj7AIZVEBx05bsxRUo,399
|
|
28
28
|
flowcept/commons/flowcept_dataclasses/task_object.py,sha256=3DD5ZNMz7EVILS9PRkQ3khboav7lIKoUC5W6sKMFauQ,4694
|
|
@@ -45,8 +45,8 @@ flowcept/flowceptor/adapters/instrumentation_interceptor.py,sha256=DhK2bBnpghqPS
|
|
|
45
45
|
flowcept/flowceptor/adapters/interceptor_state_manager.py,sha256=xRzmi5YFKBEqNtX8F5s6XlMTRe27ml4BmQtBO4WtG2c,919
|
|
46
46
|
flowcept/flowceptor/adapters/dask/__init__.py,sha256=GKreb5L_nliD2BEckyB943zOQ-b6Gn1fLDj81FqSK2Y,23
|
|
47
47
|
flowcept/flowceptor/adapters/dask/dask_dataclasses.py,sha256=6LTG-kdcc6AUuVINvkqB5QHw6pchg1aMqj0sdWt2Ef8,580
|
|
48
|
-
flowcept/flowceptor/adapters/dask/dask_interceptor.py,sha256=
|
|
49
|
-
flowcept/flowceptor/adapters/dask/dask_plugins.py,sha256=
|
|
48
|
+
flowcept/flowceptor/adapters/dask/dask_interceptor.py,sha256=Dzrwu9Y9A6k2Qq8tZKXx3zmi-CpmtFrJehUTfNjZxDM,5827
|
|
49
|
+
flowcept/flowceptor/adapters/dask/dask_plugins.py,sha256=s1ENAi9N61PC_6RiFvOYhJsgWzSm_lFWm3w87V-R1YY,2473
|
|
50
50
|
flowcept/flowceptor/adapters/mlflow/__init__.py,sha256=3mzHrvh1XQOy68qx1A3so9Nq27tIb0i2mSXfv3F6gZg,25
|
|
51
51
|
flowcept/flowceptor/adapters/mlflow/interception_event_handler.py,sha256=-SsIRdOcZjQUTzWgsZ41ouqpla4Qd32jIWXIAGU1pPw,494
|
|
52
52
|
flowcept/flowceptor/adapters/mlflow/mlflow_dao.py,sha256=dPEgCduiw14_pzT5WCjuokwaN7p5Tu7UvWS2rtGh4qk,4589
|
|
@@ -60,14 +60,14 @@ flowcept/flowceptor/adapters/zambeze/zambeze_dataclasses.py,sha256=nn9MxvcdzgmOa
|
|
|
60
60
|
flowcept/flowceptor/adapters/zambeze/zambeze_interceptor.py,sha256=Bjyi48JW0DXJLJuvwPxaD8zxxsSoEFgSoXl8YcbwFWk,3782
|
|
61
61
|
flowcept/flowceptor/consumers/__init__.py,sha256=foxtVEb2ZEe9g1slfYIKM4tIFv-He1l7XS--SYs7nlQ,28
|
|
62
62
|
flowcept/flowceptor/consumers/consumer_utils.py,sha256=JmyjQeZPqMj_yqFlxxw9k2_JZvZkAmX7kySV__YvEVc,5719
|
|
63
|
-
flowcept/flowceptor/consumers/document_inserter.py,sha256=
|
|
63
|
+
flowcept/flowceptor/consumers/document_inserter.py,sha256=rAK3rs3VNW5a6koesE05scQ1mR_4BhuxLurP10ipURs,9339
|
|
64
64
|
flowcept/instrumentation/__init__.py,sha256=M5bTmg80E4QyN91gUX3qfw_nbtJSXwGWcKxdZP3vJz0,34
|
|
65
65
|
flowcept/instrumentation/flowcept_loop.py,sha256=9Ap7-PfpNdwS7DaRDaB-R9G3X_G3RZvGVkNVUZAix5A,12164
|
|
66
66
|
flowcept/instrumentation/flowcept_task.py,sha256=l_BAYEUZ_SeBt8QJN_E9D9QcZVYRnW9qO_XRnqvmePE,5993
|
|
67
67
|
flowcept/instrumentation/flowcept_torch.py,sha256=KXA1HBwz8l5Qp7PkZ7nsbYlM8IcwWD_u04NxaAcZPzM,23395
|
|
68
68
|
flowcept/instrumentation/task_capture.py,sha256=u82r_SgzoVKyb6_SWtfB-meBUZgjrXvF5dxkH9vnMDs,4776
|
|
69
|
-
resources/sample_settings.yaml,sha256=
|
|
70
|
-
flowcept-0.8.
|
|
71
|
-
flowcept-0.8.
|
|
72
|
-
flowcept-0.8.
|
|
73
|
-
flowcept-0.8.
|
|
69
|
+
resources/sample_settings.yaml,sha256=eYMO3rlS4m1sjkgoKuRIYaTuZldiu50bN-E3Bu3on_I,3424
|
|
70
|
+
flowcept-0.8.4.dist-info/METADATA,sha256=aOyqBxuMdXSO5h4n9vAqLQDY7U3ZRRzJoHKTrgHYfoE,17543
|
|
71
|
+
flowcept-0.8.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
72
|
+
flowcept-0.8.4.dist-info/licenses/LICENSE,sha256=r5-2P6tFTuRGWT5TiX32s1y0tnp4cIqBEC1QjTaXe2k,1086
|
|
73
|
+
flowcept-0.8.4.dist-info/RECORD,,
|
resources/sample_settings.yaml
CHANGED
|
File without changes
|
|
File without changes
|