Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def delete_label(app: App, label: LabelRef) -> None:
"""
Deletes the metadata for a label and marks the label as deleted.
The history for the label is not changed (in order to allow post-hoc
analysis of the path the label took through the state machine).
"""
state_machine = get_state_machine(app, label) # Raises UnknownStateMachine
try:
row = lock_label(app, label)
except UnknownLabel:
return
if row is None or row.deleted:
return
# Record the label as having been deleted and remove its metadata
row.metadata = {}
row.deleted = True
# Add a history entry for the deletion
current_state = get_current_state(app, label, state_machine)
if current_state is None:
raise AssertionError(f"Active label {label} has no current state!")
def _process_transitions_for_metadata_update(
app: App,
label: LabelRef,
state_machine: StateMachine,
state_pending_update: State,
):
with app.session.begin_nested():
lock_label(app, label)
current_state = get_current_state(app, label, state_machine)
if state_pending_update != current_state:
# We have raced with another update, and are no longer in
# the state for which we needed an update, so we should
# stop.
return
if not isinstance(current_state, Gate): # pragma: no branch
# Cannot be hit because of the semantics of
# `needs_gate_evaluation_for_metadata_change`. Here to
# appease mypy.
raise RuntimeError( # pragma: no cover
"Label not in a gate",
)
def _transition() -> bool:
with app.session.begin_nested():
lock_label(app, label)
current_state = get_current_state(app, label, state_machine)
if isinstance(current_state, Action):
return process_action(
app=app,
state=current_state,
state_machine=state_machine,
label=label,
)
elif isinstance(current_state, Gate): # pragma: no branch
if not current_state.trigger_on_entry:
return False
return process_gate(
app=app,
state_machine: StateMachine,
state: State,
):
"""
Cron event entrypoint.
"""
with app.new_session():
relevant_labels = get_labels(state_machine, state)
for label_name in relevant_labels:
with suppress_exceptions(app.logger):
label = LabelRef(name=label_name, state_machine=state_machine.name)
could_progress = False
with app.new_session():
lock_label(app, label)
current_state = get_current_state(app, label, state_machine)
if current_state != state:
continue
could_progress = process(
app=app,
state=state,
state_machine=state_machine,
label=label,
)
with app.new_session():
if could_progress:
process_transitions(app, label)
def update_metadata_for_label(
app: App,
label: LabelRef,
update: Metadata,
) -> Metadata:
"""
Updates the metadata for a label.
Moves the label through the state machine as appropriate.
"""
state_machine = get_state_machine(app, label)
needs_gate_evaluation = False
row = lock_label(app, label)
existing_metadata, deleted = row.metadata, row.deleted
if deleted:
raise DeletedLabel(label)
needs_gate_evaluation, current_state = \
needs_gate_evaluation_for_metadata_change(
app,
state_machine,
label,
update,
)
new_metadata = dict_merge(existing_metadata, update)
row.metadata = new_metadata