https://dagster.io/ logo
Title
m

Michel Rouly

06/16/2021, 7:03 PM
Hey y'all. Seeing something fucky with sensors. I have a sensor function (which returns a generator) decorated with
@sensor
, and I have the same function (copy/paste) passed into an explicit
SensorDefinition
call as the
evaluation_fn
. But the decorated function is working, whereas the
SensorDefinition
instance I'm constructing is not doing anything. Specifically, it sets up and runs as a sensor, but it's not invoking the
evaluation_fn
as far as I can tell. Any idea what I need to do before calling
SensorDefinition
if I'm not able to use
@sensor
? Would be super helpful 🙂
d

daniel

06/16/2021, 7:04 PM
HI Michael - is it possible to post the code with the SensorDefinition?
m

Michel Rouly

06/16/2021, 7:05 PM
Yeah, give me a moment to get a minimal case. One minute 🙂
🙏 1
@sensor(
    name="update_clustering_sensor",
    pipeline_name="update_clustering_pipeline",
    mode="s3",
    minimum_interval_seconds=10,
)
def decorated_sensor(context: SensorExecutionContext) -> Generator:
    print("decorated_sensor")
    yield SkipReason("No solids were added or updated.")

def build_sensor(mode: str) -> SensorDefinition:
    return SensorDefinition(
        name="update_clustering_sensor",
        pipeline_name="update_clustering_pipeline",
        mode=mode,
        minimum_interval_seconds=30,
        evaluation_fn=sensor_fn,
    )

def sensor_fn(context: SensorExecutionContext) -> Generator:
    print("sensor_fn")
    yield SkipReason("No solids were added or updated.")
Something like this.
The main reason behind this is the ability to parameterize
mode
as I've done in
build_sensor
.
In this example, I wouldn't ever see
sensor_fn
printed out during sensor execution.
d

daniel

06/16/2021, 7:08 PM
just confirming -
update_clustering_sensor_fn
should be
sensor_fn
?
m

Michel Rouly

06/16/2021, 7:08 PM
yeah, typo in the example. will update.
d

daniel

06/16/2021, 7:10 PM
and in your repository I assume you include
build_sensor()
(with parens) where you had
decorated_sensor
(without parens) before?
m

Michel Rouly

06/16/2021, 7:10 PM
Correct
p

prha

06/16/2021, 7:12 PM
@Michel Rouly are you including both functions in your repo, or just one? I noticed that both of the sensors have the same name, and we enforce uniqueness at the repository level for sensors
m

Michel Rouly

06/16/2021, 7:12 PM
I'm definitely not a Python decorator expert, but it looks like there's some generator unpacking going on in
@sensor
that may be relevant? There's also the
decorated_fn
field in
SensorDefinition
that
@sensor
parameterizes, but I'm not.
@prha good question, only one at a time.
d

daniel

06/16/2021, 7:13 PM
hmmm, I'm seeing ticks happen when I paste in build_sensor("default") into my list of sensors. Could you post your repository too just to see if there's anything surprising there?
Specifically when I turn the sensor on and go to the timeline in dagit, I see a "Skipped No solids were added or updated." entry
I agree that unpacking should probably go inside SensorDefinition so that all sensors can take advantage of the validation - but i think it should still work without it as long as your evaluation_fn is a generator
m

Michel Rouly

06/16/2021, 7:18 PM
Hmm. We're switching our sensor code to this demo as we've been talking and now we're not seeing any logging emitted.
Give me a minute or two to double check that the demo I gave you is correct 😓
Now with our production code with
@sensor
that used to work back in our repo definition, we're just actually not even seeing ticks anymore. Something strange is afoot. Will update.
d

daniel

06/16/2021, 7:22 PM
gotcha - there might be some clues in your daemon output or errors on the Status page in dagit
m

Michel Rouly

06/16/2021, 7:25 PM
The only logs of interest I'm getting are
2021-06-16 15:24:39 - BackfillDaemon - INFO - No backfill jobs requested.
2021-06-16 15:24:39 - SchedulerDaemon - INFO - Not checking for any runs since no schedules have been started.
ok, fun information. we blew away
$DAGSTER_HOME
and restarted the daemon and dagit and our sensor is back to working.
our original, prod sensor, decorated with
@sensor
and after nuking
$DAGSTER_HOME
a second time, our
SensorDefinition
based sensor is working as expected.
so... tl;dr: invoking
SensorDefinition
directly does work, but either that or simply having multiple sensors of the same names active at different times (i.e., not concurrently) may corrupt the
$DAGSTER_HOME
directory?
p

prha

06/16/2021, 7:35 PM
I’m not sure what the dagster home directory would have to do with anything, to be honest. What are you using for your
schedule_storage
? sqlite? postgres?
m

Michel Rouly

06/16/2021, 7:35 PM
This is entirely local on a laptop, defaults for everything 🙂
p

prha

06/16/2021, 7:43 PM
hmm, I was able to switch from the decorated to the
SensorDefinition
version successfully without blowing away dagster home or even restarting the daemon
as far as i can tell, we identify each sensor instance by its name, so there shouldn’t be any artifacts stored anywhere that would cause any conflicts
the daemon, however, takes around 60 seconds to pick up any repository changes
(while running)
m

Michel Rouly

06/16/2021, 7:46 PM
we were killing and restarting the daemon every time code was changed
we've still got the old potentially corrupted
$DAGSTER_HOME
directory if analysis on that would be helpful, we backed it up before blowing it away