Hi all, I've been testing new caching feature, and...
# hamilton-help
m
Hi all, I've been testing new caching feature, and I'm running into an issue. I have a node that's not supposed to be cached, so I set it to
@cache(behavior="ignore")
but it still tries to cache it and crashes (it's not a data object, has some stuff that can't be pickled). but if I try "disable", it doesn't cache it. but there's a difference between those, right? my understanding is that ignore will not use it for caching in any way, but also not affect the downstream deps, whereas disable will, is that correct?
t
Hi Michal! I think you found the bug! Here are some additional info: ## issue
so I set it to
@cache(behavior="ignore")
but it still tries to cache it and crashes (it's not a data object, has some stuff that can't be pickled).
Just so I understand, adding
.with_cache()
and then calling
.execute()
on that node makes execution crash / raise an error? If this is the case, it's an undesirable behavior that we would like to catch. Do you have a small repro or what object type causes the crash? ## concepts
IGNORE
vs.
DISABLE
The difference between the two is subtle, so I'll reference a part of the docs for context. In the
DEFAULT
behavior:
1. Before execution: determine the
cache_key
2. At execution:
a. if the
cache_key
finds a match in the metadata store (cache hit), retrieve the
data_version
of the
result
.
b. If there’s no match (cache miss), execute the node and store the
data_version
of the
result
in the metadata store.
• After execution: if we had to execute the node, store the
result
in the result store.
The intended behavior (I think there's a bug with
IGNORE
) • `DISABLE`: does none of the above. It really is equivalent to not having
.with_cache()
• `IGNORE`: the goal of ignore is to say "do not consider this node in downstream `cache_key`" ## example To illustrate, we have a ML training dataflow, where
trained_model
depends on
processed_data
and
hparam
. Our goal is to try the same
hparam
with the same data. Setting
DISABLE
on
processed_data
means it will never be assigned a
data_version
nor have its results stored. When creating the
cache_key
for
trained_model
it will always be a cache miss because there's no
data_version
for
processed_data
(internally, we use a random value)
Copy code
@cache(behavior="disable")
def processed_data(raw_data: pd.DataFrame) -> pd.DataFrame: ...

def trained_model(processed_data: pd.DataFrame, hparam: int) -> XGBRegressor: ...
Setting
IGNORE
on
processed_data
means we shouldn't produce a
data_version
for it (maybe it's unhashable). When creating the
cache_key
for
trained_model
, only the
data_version
of
hparam
will be included in dependencies (internally, we use a constant for
processed_data
)
Copy code
@cache(behavior="ignore")
def processed_data(raw_data: pd.DataFrame) -> pd.DataFrame: ...

def trained_model(processed_data: pd.DataFrame, hparam: int) -> XGBRegressor: ...
but yes, I think you identified a bug because
IGNORE
tries to compute a
data_version
somewhere
m
hey, thanks for the reply; just to be clear, the crash itself is due to the fact that the value that is being cached can't be serialized. that part makes sense to me. the part that doesn't is that it tries to cache it.
and thanks for the detailed explanation. I think I get it 😂
t
Caching still makes my head spin, so it's a good exercise to try to explain it. I'll keep adding to the docs