diff --git a/pyproject.toml b/pyproject.toml index 9f59cefa..239bd3cb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,11 +4,11 @@ build-backend = "setuptools.build_meta" [project] name = "julee" -version = "0.1.8" +version = "0.1.9" description = "Julee - Clean architecture for accountable and transparent digital supply chains" readme = "README.md" requires-python = ">=3.11" -license = {text = "GPL-3.0"} +license = "GPL-3.0" authors = [ {name = "Pyx Industries", email = "chris@pyx.io"} ] @@ -16,7 +16,7 @@ keywords = ["temporal", "workflow", "document-processing", "ai", "supply-chain"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", - "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", diff --git a/src/julee/__init__.py b/src/julee/__init__.py index 057f4c9e..ea2600f2 100644 --- a/src/julee/__init__.py +++ b/src/julee/__init__.py @@ -1,3 +1,3 @@ """Julee - Clean architecture for accountable and transparent digital supply chains.""" -__version__ = "0.1.8" +__version__ = "0.1.9" diff --git a/src/julee/contrib/polling/domain/models/__init__.py b/src/julee/contrib/polling/domain/models/__init__.py index 0735ebbb..3955e612 100644 --- a/src/julee/contrib/polling/domain/models/__init__.py +++ b/src/julee/contrib/polling/domain/models/__init__.py @@ -6,7 +6,7 @@ No re-exports to avoid import chains that pull non-deterministic code into Temporal workflows. Import directly from specific modules: -- from julee.contrib.polling.domain.models.polling_config import PollingConfig, PollingProtocol, PollingResult +- from julee.contrib.polling.domain.models.polling_config import PollingConfig, PollingProtocol, PollingResult, SchedulingPolicy """ __all__ = [] diff --git a/src/julee/contrib/polling/domain/models/polling_config.py b/src/julee/contrib/polling/domain/models/polling_config.py index 588081cd..bc47c955 100644 --- a/src/julee/contrib/polling/domain/models/polling_config.py +++ b/src/julee/contrib/polling/domain/models/polling_config.py @@ -18,6 +18,13 @@ class PollingProtocol(str, Enum): HTTP = "http" +class SchedulingPolicy(str, Enum): + """Scheduling policy for polling operations.""" + + ALLOW_OVERLAP = "allow_overlap" + SKIP_IF_RUNNING = "skip_if_running" + + class PollingConfig(BaseModel): """Configuration for a polling operation.""" @@ -26,6 +33,10 @@ class PollingConfig(BaseModel): connection_params: dict[str, Any] = Field(default_factory=dict) polling_params: dict[str, Any] = Field(default_factory=dict) timeout_seconds: int | None = Field(default=30) + scheduling_policy: SchedulingPolicy = Field( + default=SchedulingPolicy.ALLOW_OVERLAP, + description="Policy for handling overlapping polling operations", + ) class PollingResult(BaseModel): diff --git a/src/julee/contrib/polling/infrastructure/temporal/manager.py b/src/julee/contrib/polling/infrastructure/temporal/manager.py index cda33493..2f82d77d 100644 --- a/src/julee/contrib/polling/infrastructure/temporal/manager.py +++ b/src/julee/contrib/polling/infrastructure/temporal/manager.py @@ -17,12 +17,17 @@ ScheduleActionStartWorkflow, ScheduleAlreadyRunningError, ScheduleIntervalSpec, + ScheduleOverlapPolicy, + SchedulePolicy, ScheduleSpec, ScheduleUpdate, ScheduleUpdateInput, ) -from julee.contrib.polling.domain.models.polling_config import PollingConfig +from julee.contrib.polling.domain.models.polling_config import ( + PollingConfig, + SchedulingPolicy, +) logger = logging.getLogger(__name__) @@ -99,6 +104,13 @@ async def start_polling( schedule_id = f"poll-{endpoint_id}" + # Map Julee scheduling policy to Temporal overlap policy + temporal_overlap_policy = ( + ScheduleOverlapPolicy.SKIP + if config.scheduling_policy == SchedulingPolicy.SKIP_IF_RUNNING + else ScheduleOverlapPolicy.ALLOW_ALL + ) + schedule = Schedule( action=ScheduleActionStartWorkflow( "NewDataDetectionPipeline", @@ -111,6 +123,7 @@ async def start_polling( ScheduleIntervalSpec(every=timedelta(seconds=interval_seconds)) ] ), + policy=SchedulePolicy(overlap=temporal_overlap_policy), ) try: