def test_subscription_resolution_larger_than_tiny_interval(self) -> None: subscription = self.build_subscription(timedelta(minutes=1)) self.run_test( [subscription], start=timedelta(seconds=-1), end=timedelta(seconds=1), expected=[ScheduledTask(self.now, subscription)], )
def test_multiple_subscriptions(self) -> None: subscription = self.build_subscription(timedelta(minutes=1)) other_subscription = self.build_subscription(timedelta(minutes=2)) expected = [ ScheduledTask(self.now + timedelta(minutes=-10 + i), subscription) for i in range(10) ] + [ ScheduledTask(self.now + timedelta(minutes=-10 + i), other_subscription) for i in range(0, 10, 2) ] expected.sort(key=self.sort_key) self.run_test( [subscription, other_subscription], start=timedelta(minutes=-10), end=timedelta(minutes=0), expected=expected, sort_key=self.sort_key, )
def test_subscription_resolution_larger_than_tiny_interval(self) -> None: state.set_config("subscription_primary_task_builder", "immediate") subscription = self.build_subscription(timedelta(minutes=1)) self.run_test( [subscription], start=timedelta(seconds=-1), end=timedelta(seconds=1), expected=[ScheduledTask(self.now, subscription)], )
def get_task( self, subscription: Subscription, timestamp: int ) -> Optional[ScheduledTask[Subscription]]: resolution = int(subscription.data.resolution.total_seconds()) if timestamp % resolution == 0: self.__count += 1 return ScheduledTask(datetime.fromtimestamp(timestamp), subscription) else: return None
def test_simple(self) -> None: subscription = self.build_subscription(timedelta(minutes=1)) self.run_test( [subscription], start=timedelta(minutes=-10), end=timedelta(minutes=0), expected=[ ScheduledTask(self.now + timedelta(minutes=-10 + i), subscription) for i in range(10) ], )
def test_simple_jittered(self) -> None: state.set_config("subscription_primary_task_builder", "jittered") subscription = self.build_subscription(timedelta(minutes=1)) self.run_test( [subscription], start=timedelta(minutes=-10), end=timedelta(minutes=0), expected=[ ScheduledTask(self.now + timedelta(minutes=-10 + i), subscription) for i in range(10) ], )
def get_task( self, subscription: Subscription, timestamp: int ) -> Optional[ScheduledTask[Subscription]]: resolution = int(subscription.data.resolution.total_seconds()) if resolution > settings.MAX_RESOLUTION_FOR_JITTER: if timestamp % resolution == 0: self.__count += 1 self.__count_max_resolution += 1 return ScheduledTask(datetime.fromtimestamp(timestamp), subscription) else: return None jitter = subscription.identifier.uuid.int % resolution if timestamp % resolution == jitter: self.__count += 1 return ScheduledTask( datetime.fromtimestamp(timestamp - jitter), subscription ) else: return None
def find( self, interval: Interval[datetime] ) -> Iterator[ScheduledTask[Subscription]]: subscriptions = self.__get_subscriptions() for timestamp in range( math.ceil(interval.lower.timestamp()), math.ceil(interval.upper.timestamp()), ): for subscription in subscriptions: resolution = int(subscription.data.resolution.total_seconds()) if timestamp % resolution == 0: yield ScheduledTask(datetime.fromtimestamp(timestamp), subscription)
def test_subscription_task_result_encoder() -> None: codec = SubscriptionTaskResultEncoder() timestamp = datetime.now() subscription_data = LegacySubscriptionData( project_id=1, conditions=[], aggregations=[["count()", "", "count"]], time_window=timedelta(minutes=1), resolution=timedelta(minutes=1), ) # XXX: This seems way too coupled to the dataset. request = subscription_data.build_request(get_dataset("events"), timestamp, None, Timer("timer")) result: Result = { "meta": [{ "type": "UInt64", "name": "count" }], "data": [{ "count": 1 }], } task_result = SubscriptionTaskResult( ScheduledTask( timestamp, Subscription( SubscriptionIdentifier(PartitionId(1), uuid.uuid1()), subscription_data, ), ), (request, result), ) message = codec.encode(task_result) data = json.loads(message.value.decode("utf-8")) assert data["version"] == 2 payload = data["payload"] assert payload["subscription_id"] == str(task_result.task.task.identifier) assert payload["request"] == request.body assert payload["result"] == result assert payload["timestamp"] == task_result.task.timestamp.isoformat()
) from snuba.utils.scheduler import ScheduledTask from tests.subscriptions.subscriptions_utils import UUIDS, build_subscription ALIGNED_TIMESTAMP = 1625518080 # Aligned to start of a minute TEST_CASES = [ pytest.param( ImmediateTaskBuilder(), "jittered", [(ALIGNED_TIMESTAMP, build_subscription(timedelta(minutes=1), 0))], [ ( ALIGNED_TIMESTAMP, ScheduledTask( datetime.fromtimestamp(ALIGNED_TIMESTAMP), build_subscription(timedelta(minutes=1), 0), ), ) ], [("tasks.built", 1, {})], id="One subscription immediately scheduled", ), pytest.param( ImmediateTaskBuilder(), "jittered", [(ALIGNED_TIMESTAMP + 1, build_subscription(timedelta(minutes=1), 0))], [], [("tasks.built", 0, {})], id="One subscription not aligned with resolution", ), pytest.param(