FireAndForgetRunner

class simstack.methods.fire_and_forget_runner.FireAndForgetRunner(node: ~typing.Callable[[...], ~typing.Any], max_concurrency: int | None = None, *, status: ~simstack.core.definitions.TaskStatus = TaskStatus.RETRIEVED, error_message: str | None = None, message: str | None = None, files: ~typing.List[~simstack.models.files.FileStack] = <factory>, info_files: ~typing.List[~simstack.models.files.FileStack] = <factory>, **kwargs)[source]

Bases: NodeRunner

create_tasks(*args: Model)[source]
model_config = {'extra': 'allow'}

Represents the results from a Simstack operation.

This class serves to encapsulate the status, messages, and files resulting from a Simstack operation. It provides structured attributes for the error message, operation message, and categorized files, ensuring clarity in the representation of these aspects. It also supports additional fields through flexible configuration.

Variables:
  • status – Indicates the status of the task, defaulting to TaskStatus.COMPLETED.

  • error_message – Optionally stores an error message if the task encountered issues.

  • message – An optional general message providing additional information about the task.

  • files – A list of FileStack objects that represent the primary files involved in the operation. Defaults to an empty list.

  • info_files – A list of FileStack objects that provide additional or informational files pertaining to the operation. Defaults to an empty list. These files are shown in the results but not passed to the calling function

The FireAndForgetRunner is a specialized NodeRunner utility designed to execute multiple independent node tasks in parallel, similar to MassRunner. However, unlike MassRunner which aggregates all results into a single DataSet, the FireAndForgetRunner persists each individual result immediately to the database as a FireAndForgetResult record.

Key Features

  • Parallel Execution: Leverages asyncio to run multiple nodes concurrently.

  • Concurrency Control: Supports an optional max_concurrency parameter using an internal semaphore.

  • Immediate Persistence: Saves a FireAndForgetResult to the database as soon as each individual node call finishes, without waiting for other tasks.

  • Result Mapping: Automatically captures and stores input arguments and return values (supporting Model, SimstackResult, and lists of Model) into a dictionary.

  • Call Path Tracking: Records the full call path for each task, facilitating traceability.

Usage

The FireAndForgetRunner is typically used within an async with block inside a parent node.

from simstack.methods.fire_and_forget_runner import FireAndForgetRunner
from simstack.models import IntData

@node
async def my_parallel_manager(count: IntData, **kwargs):
    # Initialize FireAndForgetRunner with the target node
    async with FireAndForgetRunner(target_node, max_concurrency=5, **kwargs) as runner:
        for i in range(count.value):
            # Create tasks for individual inputs
            runner.create_tasks(IntData(value=i))

    # After the block, all tasks are finished and persisted individually
    return True

Each call to a node via FireAndForgetRunner creates a FireAndForgetResult entry in the database.

FireAndForgetResult Model

Each result is stored using the FireAndForgetResult model:

class simstack.models.fire_and_forget_result.FireAndForgetResult(*, call_path: str, models: dict[str, ~typing.Any], success: bool, next_step: bool = False, id: ~odmantic.bson.ObjectId = <factory>)[source]

Bases: Model

Model representing the result of a fire-and-forget task.

call_path

The full call path of the node.

Type:

str

models

A dictionary mapping argument/result names to their values.

Type:

dict[str, Any]

success

Whether the task was successful.

Type:

bool

next_step

Whether this result triggers a next step.

Type:

bool

call_path: str = <odmantic.field.FieldProxy object>
async custom_model_dump(**kwargs) Dict[str, Any]

Custom model dump method to handle the conversion of model instances to dictionaries. This method recursively traverses dictionaries and lists to convert any nested model instances to their dictionary representation.

Parameters:
  • self – The model instance

  • kwargs – Additional keyword arguments

Returns:

A dictionary representation of the model instance

classmethod from_dict(data: dict, **kwargs) Any

Create an instance of the model from a dictionary. Handles nested models and enum values.

classmethod from_model(model: Model, **kwargs) Model
id: ObjectId = <odmantic.field.FieldProxy object>
classmethod json_schema()

Generates a JSON schema for the given class and its fields, but eliminates all fields which are models, embedded models, or references to models.

Parameters:

cls

Returns:

model_config = {'arbitrary_types_allowed': False, 'collection': None, 'extra': None, 'indexes': None, 'json_schema_extra': None, 'parse_doc_with_default_factories': False, 'str_strip_whitespace': False, 'title': None, 'validate_assignment': True, 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

models: dict[str, Any] = <odmantic.field.FieldProxy object>
next_step: bool = <odmantic.field.FieldProxy object>
success: bool = <odmantic.field.FieldProxy object>
classmethod ui_make_title(ui_schema: Dict[str, Any], field: str, title: str) dict

Adds a title to the JSON schema.

Parameters:
  • cls – The class to which the JSON schema belongs

  • ui_schema – The original ui_schema schema

  • title – Title to be added

Returns:

Modified JSON schema with title

classmethod ui_schema()

Generates a UI schema that uses GenericForm for fields with ui_schema function. Also preserves any existing UI schema configurations from the class.

Parameters:

cls – The model class to generate UI schema for

Returns:

The generated UI schema

Return type:

dict

Fields:

  • call_path: A string representing the concatenated path of the runner and the node (e.g., /my_parallel_manager/target_node).

  • models: A dictionary containing all input arguments (prefixed with arg_) and output results (prefixed with result_).

  • success: A boolean flag indicating if the node call was successful.

  • next_step: A boolean flag indicating if this result triggers a next step.

Comparison with MassRunner

While both runners facilitate parallel execution, they serve different persistence needs:

  • MassRunner: Best for batch jobs where you want a single consolidated DataSet at the end. It supports result recovery and caching based on argument hashes.

  • FireAndForgetRunner: Best for scenarios where you want immediate visibility of results as they arrive, or when the number of tasks is extremely large and you want to avoid holding all results in memory/aggregated model before saving. It does not currently support the same recovery/caching mechanisms as MassRunner.