Skip to content

Commit

Permalink
Optimize deferrable mode in GCSObjectExistenceSensor (#30901)
Browse files Browse the repository at this point in the history
* optimize deferrable mode in GCSObjectExistenceSensor
  • Loading branch information
phanikumv committed Apr 27, 2023
1 parent 1132da1 commit 3a5b583
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
27 changes: 14 additions & 13 deletions airflow/providers/google/cloud/sensors/gcs.py
Expand Up @@ -101,19 +101,20 @@ def execute(self, context: Context) -> None:
if not self.deferrable:
super().execute(context)
else:
self.defer(
timeout=timedelta(seconds=self.timeout),
trigger=GCSBlobTrigger(
bucket=self.bucket,
object_name=self.object,
poke_interval=self.poke_interval,
google_cloud_conn_id=self.google_cloud_conn_id,
hook_params={
"impersonation_chain": self.impersonation_chain,
},
),
method_name="execute_complete",
)
if not self.poke(context=context):
self.defer(
timeout=timedelta(seconds=self.timeout),
trigger=GCSBlobTrigger(
bucket=self.bucket,
object_name=self.object,
poke_interval=self.poke_interval,
google_cloud_conn_id=self.google_cloud_conn_id,
hook_params={
"impersonation_chain": self.impersonation_chain,
},
),
method_name="execute_complete",
)

def execute_complete(self, context: Context, event: dict[str, str]) -> str:
"""
Expand Down
22 changes: 20 additions & 2 deletions tests/providers/google/cloud/sensors/test_gcs.py
Expand Up @@ -99,7 +99,22 @@ def test_should_pass_argument_to_hook(self, mock_hook):
)
mock_hook.return_value.exists.assert_called_once_with(TEST_BUCKET, TEST_OBJECT, DEFAULT_RETRY)

def test_gcs_object_existence_sensor_deferred(self):
@mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSHook")
@mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSObjectExistenceSensor.defer")
def test_gcs_object_existence_sensor_finish_before_deferred(self, mock_defer, mock_hook):
task = GCSObjectExistenceSensor(
task_id="task-id",
bucket=TEST_BUCKET,
object=TEST_OBJECT,
google_cloud_conn_id=TEST_GCP_CONN_ID,
deferrable=True,
)
mock_hook.return_value.exists.return_value = True
task.execute(mock.MagicMock())
assert not mock_defer.called

@mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSHook")
def test_gcs_object_existence_sensor_deferred(self, mock_hook):
"""
Asserts that a task is deferred and a GCSBlobTrigger will be fired
when the GCSObjectExistenceSensor is executed and deferrable is set to True.
Expand All @@ -111,6 +126,7 @@ def test_gcs_object_existence_sensor_deferred(self):
google_cloud_conn_id=TEST_GCP_CONN_ID,
deferrable=True,
)
mock_hook.return_value.exists.return_value = False
with pytest.raises(TaskDeferred) as exc:
task.execute(context)
assert isinstance(exc.value.trigger, GCSBlobTrigger), "Trigger is not a GCSBlobTrigger"
Expand Down Expand Up @@ -147,7 +163,8 @@ class TestGoogleCloudStorageObjectSensorAsync:
"Please use `GCSObjectExistenceSensor` and set `deferrable` attribute to `True` instead"
)

def test_gcs_object_existence_sensor_async(self):
@mock.patch("airflow.providers.google.cloud.sensors.gcs.GCSHook")
def test_gcs_object_existence_sensor_async(self, mock_hook):
"""
Asserts that a task is deferred and a GCSBlobTrigger will be fired
when the GCSObjectExistenceAsyncSensor is executed.
Expand All @@ -159,6 +176,7 @@ def test_gcs_object_existence_sensor_async(self):
object=TEST_OBJECT,
google_cloud_conn_id=TEST_GCP_CONN_ID,
)
mock_hook.return_value.exists.return_value = False
with pytest.raises(TaskDeferred) as exc:
task.execute(context)
assert isinstance(exc.value.trigger, GCSBlobTrigger), "Trigger is not a GCSBlobTrigger"
Expand Down

0 comments on commit 3a5b583

Please sign in to comment.