def METHOD_NAME(app: App, body: PredictBody):
    fn_index = body.fn_index
    session_hash = getattr(body, "session_hash", None)
    if session_hash is not None:
        if session_hash not in app.state_holder:
            app.state_holder[session_hash] = {
                _id: deepcopy(getattr(block, "value", None))
                for _id, block in app.get_blocks().blocks.items()
                if getattr(block, "stateful", False)
            }
        session_state = app.state_holder[session_hash]
        # The should_reset set keeps track of the fn_indices
        # that have been cancelled. When a job is cancelled,
        # the /reset route will mark the jobs as having been reset.
        # That way if the cancel job finishes BEFORE the job being cancelled
        # the job being cancelled will not overwrite the state of the iterator.
        if fn_index in app.iterators_to_reset[session_hash]:
            iterators = {}
            app.iterators_to_reset[session_hash].remove(fn_index)
        else:
            iterators = app.iterators[session_hash]
    else:
        session_state = {}
        iterators = {}
    return session_state, iterators