@@ -74,15 +74,12 @@ def my_task_function(self, task_context: TaskContext) -> None:
7474 ExtractorInfo ,
7575 StartupRequest ,
7676 TaskType ,
77- TaskUpdate ,
78- )
79- from cognite .extractorutils .unstable .core ._dto import (
80- Error as DtoError ,
8177)
8278from cognite .extractorutils .unstable .core ._dto import (
8379 Task as DtoTask ,
8480)
8581from cognite .extractorutils .unstable .core ._messaging import RuntimeMessage
82+ from cognite .extractorutils .unstable .core .checkin_worker import CheckinWorker
8683from cognite .extractorutils .unstable .core .errors import Error , ErrorLevel
8784from cognite .extractorutils .unstable .core .logger import CogniteLogger
8885from cognite .extractorutils .unstable .core .restart_policy import WHEN_CONTINUOUS_TASKS_CRASHES , RestartPolicy
@@ -142,8 +139,11 @@ class Extractor(Generic[ConfigType], CogniteLogger):
142139
143140 RESTART_POLICY : RestartPolicy = WHEN_CONTINUOUS_TASKS_CRASHES
144141
145- def __init__ (self , config : FullConfig [ConfigType ]) -> None :
142+ cancellation_token : CancellationToken
143+
144+ def __init__ (self , config : FullConfig [ConfigType ], checkin_worker : CheckinWorker ) -> None :
146145 self ._logger = logging .getLogger (f"{ self .EXTERNAL_ID } .main" )
146+ self ._checkin_worker = checkin_worker
147147
148148 self .cancellation_token = CancellationToken ()
149149 self .cancellation_token .cancel_on_interrupt ()
@@ -161,8 +161,6 @@ def __init__(self, config: FullConfig[ConfigType]) -> None:
161161 self ._scheduler = TaskScheduler (self .cancellation_token .create_child_token ())
162162
163163 self ._tasks : list [Task ] = []
164- self ._task_updates : list [TaskUpdate ] = []
165- self ._errors : dict [str , Error ] = {}
166164 self ._start_time : datetime
167165
168166 self .__init_tasks__ ()
@@ -253,43 +251,6 @@ def _attach_runtime_controls(self, *, cancel_event: MpEvent, message_queue: Queu
253251 self ._set_runtime_message_queue (message_queue )
254252 self ._setup_cancellation_watcher (cancel_event )
255253
256- def _checkin (self ) -> None :
257- with self ._checkin_lock :
258- task_updates = [t .model_dump (mode = "json" ) for t in self ._task_updates ]
259- self ._task_updates .clear ()
260-
261- error_updates = [
262- DtoError (
263- external_id = e .external_id ,
264- level = e .level ,
265- description = e .description ,
266- details = e .details ,
267- start_time = e .start_time ,
268- end_time = e .end_time ,
269- task = e ._task_name if e ._task_name is not None else None ,
270- ).model_dump (mode = "json" )
271- for e in self ._errors .values ()
272- ]
273- self ._errors .clear ()
274-
275- res = self .cognite_client .post (
276- f"/api/v1/projects/{ self .cognite_client .config .project } /integrations/checkin" ,
277- json = {
278- "externalId" : self .connection_config .integration .external_id ,
279- "taskEvents" : task_updates ,
280- "errors" : error_updates ,
281- },
282- headers = {"cdf-version" : "alpha" },
283- )
284- new_config_revision = res .json ().get ("lastConfigRevision" )
285-
286- if (
287- new_config_revision
288- and self .current_config_revision != "local"
289- and new_config_revision > self .current_config_revision
290- ):
291- self .restart ()
292-
293254 def _get_startup_request (self ) -> StartupRequest :
294255 return StartupRequest (
295256 external_id = self .connection_config .integration .external_id ,
@@ -310,17 +271,10 @@ def _get_startup_request(self) -> StartupRequest:
310271 )
311272
312273 def _run_checkin (self ) -> None :
313- while not self .cancellation_token .is_cancelled :
314- try :
315- self ._logger .debug ("Running checkin" )
316- self ._checkin ()
317- except Exception :
318- self ._logger .exception ("Error during checkin" )
319- self .cancellation_token .wait (10 )
274+ self ._checkin_worker .run_periodic_checkin (self .cancellation_token , self ._get_startup_request ())
320275
321276 def _report_error (self , error : Error ) -> None :
322- with self ._checkin_lock :
323- self ._errors [error .external_id ] = error
277+ self ._checkin_worker .report_error (error )
324278
325279 def _new_error (
326280 self ,
@@ -348,8 +302,8 @@ def restart(self) -> None:
348302 self .cancellation_token .cancel ()
349303
350304 @classmethod
351- def _init_from_runtime (cls , config : FullConfig [ConfigType ]) -> Self :
352- return cls (config )
305+ def _init_from_runtime (cls , config : FullConfig [ConfigType ], checkin_worker : CheckinWorker ) -> Self :
306+ return cls (config , checkin_worker )
353307
354308 def add_task (self , task : Task ) -> None :
355309 """
@@ -368,10 +322,7 @@ def run_task(task_context: TaskContext) -> None:
368322 A wrapped version of the task's target, with tracking and error handling.
369323 """
370324 # Record a task start
371- with self ._checkin_lock :
372- self ._task_updates .append (
373- TaskUpdate (type = "started" , name = task .name , timestamp = now ()),
374- )
325+ self ._checkin_worker .report_task_start (name = task .name , timestamp = now ())
375326
376327 try :
377328 # Run task
@@ -390,10 +341,7 @@ def run_task(task_context: TaskContext) -> None:
390341
391342 finally :
392343 # Record task end
393- with self ._checkin_lock :
394- self ._task_updates .append (
395- TaskUpdate (type = "ended" , name = task .name , timestamp = now ()),
396- )
344+ self ._checkin_worker .report_task_end (name = task .name , timestamp = now ())
397345
398346 task .target = run_task
399347 self ._tasks .append (task )
@@ -411,13 +359,6 @@ def run_task(task_context: TaskContext) -> None:
411359 ),
412360 )
413361
414- def _report_extractor_info (self ) -> None :
415- self .cognite_client .post (
416- f"/api/v1/projects/{ self .cognite_client .config .project } /integrations/extractorinfo" ,
417- json = self ._get_startup_request ().model_dump (mode = "json" ),
418- headers = {"cdf-version" : "alpha" },
419- )
420-
421362 def start (self ) -> None :
422363 """
423364 Start the extractor.
@@ -427,7 +368,6 @@ def start(self) -> None:
427368 """
428369 self ._setup_logging ()
429370 self ._start_time = datetime .now (tz = timezone .utc )
430- self ._report_extractor_info ()
431371 Thread (target = self ._run_checkin , name = "ExtractorCheckin" , daemon = True ).start ()
432372
433373 def stop (self ) -> None :
@@ -456,10 +396,7 @@ def __exit__(
456396 Stop the extractor when exiting the context manager.
457397 """
458398 self .stop ()
459- with self ._checkin_lock :
460- self ._checkin ()
461-
462- self ._logger .info ("Shutting down extractor" )
399+ self ._checkin_worker .flush (self .cancellation_token )
463400 return exc_val is None
464401
465402 def run (self ) -> None :
0 commit comments