Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cancel Snapshot Jobs #596

Closed
fredfortier opened this issue Nov 5, 2022 · 11 comments · Fixed by #816
Closed

Cancel Snapshot Jobs #596

fredfortier opened this issue Nov 5, 2022 · 11 comments · Fixed by #816
Assignees

Comments

@fredfortier
Copy link

fredfortier commented Nov 5, 2022

Is it possible to cancel a RaftSnapshotBuilder::build_snapshot job? In my context, it would simplify things to skip snapshots in particular conditions until the state machine steps into a different state. I simply want the job to try again until a snapshot is successfully returned. I tried returning this error: StorageIOError::new(ErrorSubject::None, ErrorVerb::Write, e.into()).into() from the leader, but it lead to a reelection instead of retrying. Is there an error kind that would lead to the behavior I'm looking for?

@github-actions
Copy link

github-actions bot commented Nov 5, 2022

👋 Thanks for opening this issue!

Get help or engage by:

  • /help : to print help messages.
  • /assignme : to assign this issue to you.

@fredfortier fredfortier changed the title Delayed Snapshot Cancel Snapshot Jobs Nov 5, 2022
@drmingdrmer drmingdrmer self-assigned this Nov 5, 2022
@drmingdrmer
Copy link
Member

The building snapshot is mainly a tokio task like this:

        tokio::spawn(
            async move {
                let f = builder.build_snapshot();
                let res = Abortable::new(f, reg).await;
                match res {
                    Ok(res) => match res {
                        Ok(snapshot) => {...}
                        Err(err) => {...}
                    },
                    Err(_aborted) => {...}
                }
            }
        );

It is possible to make it an infinite loop in which it retries calling build_snapshot() until it returns an OK.

Another way is to block inside build_snapshot() until some condition become ready, e.g.:

async fn build_snapshot() {
   while !is_ready().await {
       tokio::time::sleep(Duration::from_millis(10)).await;
   }
}

Does this approach address your issue?

A StorageError is a fatal error. Returning it will just shut RaftCore down at once.

Introducing another TryAgainLater error will move this logic out of build_snapshot() and simplify the implementation of build_snapshot(). But in this way, the user application can not notify RaftCore as soon as it becomes ready.

@fredfortier
Copy link
Author

fredfortier commented Nov 5, 2022

The building snapshot is mainly a tokio task like this:

        tokio::spawn(
            async move {
                let f = builder.build_snapshot();
                let res = Abortable::new(f, reg).await;
                match res {
                    Ok(res) => match res {
                        Ok(snapshot) => {...}
                        Err(err) => {...}
                    },
                    Err(_aborted) => {...}
                }
            }
        );

It is possible to make it an infinite loop in which it retries calling build_snapshot() until it returns an OK.

Another way is to block inside build_snapshot() until some condition become ready, e.g.:

async fn build_snapshot() {
   while !is_ready().await {
       tokio::time::sleep(Duration::from_millis(10)).await;
   }
}

Does this approach address your issue?

A StorageError is a fatal error. Returning it will just shut RaftCore down at once.

Introducing another TryAgainLater error will move this logic out of build_snapshot() and simplify the implementation of build_snapshot(). But in this way, the user application can not notify RaftCore as soon as it becomes ready.

Thanks for the thoughtful explanation and guidance! My initial fear was that such solution would cause tasks to accumulate. With additional clarity from your guidance, it now feels like the obvious solution to me as well. We already wait for state machine backup jobs to complete in the build_snapshot() future, so this solution fits perfectly.

@fredfortier
Copy link
Author

fredfortier commented May 2, 2023

The building snapshot is mainly a tokio task like this:

        tokio::spawn(
            async move {
                let f = builder.build_snapshot();
                let res = Abortable::new(f, reg).await;
                match res {
                    Ok(res) => match res {
                        Ok(snapshot) => {...}
                        Err(err) => {...}
                    },
                    Err(_aborted) => {...}
                }
            }
        );

It is possible to make it an infinite loop in which it retries calling build_snapshot() until it returns an OK.

Another way is to block inside build_snapshot() until some condition become ready, e.g.:

async fn build_snapshot() {
   while !is_ready().await {
       tokio::time::sleep(Duration::from_millis(10)).await;
   }
}

Does this approach address your issue?

A StorageError is a fatal error. Returning it will just shut RaftCore down at once.

Introducing another TryAgainLater error will move this logic out of build_snapshot() and simplify the implementation of build_snapshot(). But in this way, the user application can not notify RaftCore as soon as it becomes ready.

I've implemented this approach. Each build snapshot awaits some state machine conditions to be satisfied, which means the build_snapshot future may be long running, which seems appropriate given that it's a batch job. This approach seemed to work okay. However, when I rebased to 1235ee4 , it seems like the Raft replicator stops appending entries when build_snapshot starts.

I haven't fully investigated the issue, there may be an external cause. I wanted to whether something about the concurrency model changed recently that could explain this behavior.

Here's some context, build_snapshot is invoked:

{"message":"close","time.busy":"312µs","time.idle":"6.85µs","target":"openraft::core::raft_core","span":{"name":"report_metrics"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"399µs","time.idle":"8.31µs","target":"openraft::core::raft_core","span":{"name":"flush_metrics"},"threadId":"ThreadId(5)"}
{"message":"call_core receives result is error: false","target":"openraft::raft","span":{"name":"call_core"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"79.0µs","time.idle":"7.27ms","target":"openraft::raft","span":{"name":"call_core"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"155µs","time.idle":"7.27ms","target":"openraft::raft","span":{"name":"client_write"},"threadId":"ThreadId(5)"}
{"message":"Waiting for next backup","target":"ddx_core::raft::store::store_impl","span":{"name":"do_build_snapshot"},"threadId":"ThreadId(5)"}

Then entries stop being applied to the state machine, these lines seem to repeating for a while. This is still a single-node cluster.

{"message":"close","time.busy":"6.41ms","time.idle":"9.44µs","target":"ddx_core::processor","span":{"request_index":"1004","success":"true","summary":"Block(542)","name":"exec"},"threadId":"ThreadId(1)"}
{"message":"Tick sent: 8997","target":"openraft::core::tick","span":{"name":"tick"},"threadId":"ThreadId(5)"}
{"message":"recv from rx_notify: Tick 8997","target":"openraft::core::raft_core","span":{"id":"0","state":"Leader","name":"handle_notify"},"threadId":"ThreadId(5)"}
{"message":"update_now: Instant { tv_sec: 1207261, tv_nsec: 717667949 }","target":"openraft::engine::time_state","span":{"id":"0","state":"Leader","name":"handle_notify"},"threadId":"ThreadId(5)"}
{"message":"received tick: 8997, now: Instant { tv_sec: 1207261, tv_nsec: 717667949 }","target":"openraft::core::raft_core","span":{"id":"0","state":"Leader","name":"handle_notify"},"threadId":"ThreadId(5)"}
{"message":"try to trigger election by tick, now: Instant { tv_sec: 1207261, tv_nsec: 717667949 }","target":"openraft::core::raft_core","span":{"name":"handle_tick_election"},"threadId":"ThreadId(5)"}
{"message":"already a leader, do not elect again","target":"openraft::core::raft_core","span":{"name":"handle_tick_election"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"77.6µs","time.idle":"9.12µs","target":"openraft::core::raft_core","span":{"name":"handle_tick_election"},"threadId":"ThreadId(5)"}
{"message":"send_heartbeat","now":"Instant { tv_sec: 1207261, tv_nsec: 717667949 }","target":"openraft::core::raft_core","span":{"id":"0","name":"send_heartbeat"},"threadId":"ThreadId(5)"}
{"message":"this node is a leader","target":"openraft::engine::engine_impl","span":{"name":"get_leader_handler_or_reject"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"50.1µs","time.idle":"10.6µs","target":"openraft::engine::engine_impl","span":{"name":"get_leader_handler_or_reject"},"threadId":"ThreadId(5)"}
{"message":"send_to_all","progress":"VecProgress { quorum_set: Joint { data: [[0]], _p: PhantomData<(u64, alloc::vec::Vec<u64>)> }, granted: Some(LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 999 }), voter_count: 1, vector: [(0, ProgressEntry { matching: Some(LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 999 }), curr_inflight_id: 0, inflight: None, searching_end: 1000 })], stat: Stat { update_count: 1000, move_count: 1000, is_quorum_count: 1000 } }","target":"openraft::engine::handler::replication_handler","span":{"name":"initiate_replication"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"89.2µs","time.idle":"5.50µs","target":"openraft::engine::handler::replication_handler","span":{"name":"initiate_replication"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"148µs","time.idle":"5.92µs","target":"openraft::engine::handler::leader_handler","span":{"name":"send_heartbeat"},"threadId":"ThreadId(5)"}
{"message":"tick triggered sending heartbeat","target":"openraft::core::raft_core","span":{"id":"0","name":"send_heartbeat"},"threadId":"ThreadId(5)"}
{"message":"close","time.busy":"411µs","time.idle":"7.48µs","target":"openraft::core::raft_core","span":{"id":"0","name":"send_heartbeat"},"threadId":"ThreadId(5)"}
{"message":"leader_step_down: node_id:0","target":"openraft::engine::engine_impl","span":{"name":"leader_step_down"},"threadId":"ThreadId(5)"}

A little later in the log, I see indication that the snapshot is in progress.

operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.734701865Z","level":"DEBUG","message":"update_matching","self":"{[Some(1-0-1000), 1001), inflight:Logs(id=0):(None, Some(1-0-1001)]}","matching":"Some(1-0-1001)","target":"openraft::progress::entry","span":{"name":"update_matching"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.73477526Z","level":"DEBUG","message":"granted after updating progress","granted":"Some(1-0-1001)","target":"openraft::engine::handler::replication_handler","span":{"name":"update_matching"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.734876288Z","level":"DEBUG","message":"close","time.busy":"9.90µs","time.idle":"6.55µs","target":"openraft::raft_state","span":{"name":"update_committed"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.734978421Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"trigger_snapshot"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.73503532Z","level":"DEBUG","message":"snapshot building is in progress, do not trigger snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"trigger_snapshot"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.735094972Z","level":"DEBUG","message":"close","time.busy":"124µs","time.idle":"8.95µs","target":"openraft::engine::handler::snapshot_handler","span":{"name":"trigger_snapshot"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.735171918Z","level":"DEBUG","message":"close","time.busy":"318µs","time.idle":"9.94µs","target":"openraft::engine::handler::replication_handler","span":{"name":"try_commit_granted"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.735241331Z","level":"DEBUG","message":"close","time.busy":"695µs","time.idle":"8.85µs","target":"openraft::engine::handler::replication_handler","span":{"name":"update_matching"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.735327176Z","level":"DEBUG","message":"send_to_all","progress":"VecProgress { quorum_set: Joint { data: [[0]], _p: PhantomData<(u64, alloc::vec::Vec<u64>)> }, granted: Some(LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 1001 }), voter_count: 1, vector: [(0, ProgressEntry { matching: Some(LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 1001 }), curr_inflight_id: 0, inflight: None, searching_end: 1002 })], stat: Stat { update_count: 1002, move_count: 1002, is_quorum_count: 1002 } }","target":"openraft::engine::handler::replication_handler","span":{"name":"initiate_replication"},"threadId":"ThreadId(2)"}

Just after, I see it trying to apply the next entry to the state machine. My snapshot size is 1000, the request after is 1001. However, the openraft apply_to_state_machine never calls into my store's implementation, which begins with a log message that never gets printed here.

operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736034612Z","level":"DEBUG","message":"queued commands: end...","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736084346Z","level":"DEBUG","message":"run command: AppendInputEntries { entries: [Entry { log_id: LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 1001 }, payload: normal }] }","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736154815Z","level":"DEBUG","message":"condition: None","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736207878Z","level":"DEBUG","message":"AppendInputEntries: [1-0-1001:normal]","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736290856Z","level":"DEBUG","message":"append_to_log","target":"openraft::core::raft_core","span":{"name":"append_to_log"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736380282Z","level":"DEBUG","message":"Appending to log","target":"ddx_core::raft::store::store_impl","span":{"name":"append_to_log"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736472764Z","level":"DEBUG","message":"close","time.busy":"90.5µs","time.idle":"11.1µs","target":"ddx_core::raft::store::store_impl","span":{"name":"append_to_log"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736569905Z","level":"DEBUG","message":"close","time.busy":"278µs","time.idle":"12.6µs","target":"openraft::core::raft_core","span":{"name":"append_to_log"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736643929Z","level":"DEBUG","message":"run command: ReplicateCommitted { committed: Some(LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 1001 }) }","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736710863Z","level":"DEBUG","message":"condition: None","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736759981Z","level":"DEBUG","message":"run command: Apply { seq: 1002, already_committed: Some(LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 1000 }), upto: LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 1001 } }","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736836035Z","level":"DEBUG","message":"condition: None","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.736911357Z","level":"DEBUG","message":"apply_to_state_machine","upto_index":"1001","target":"openraft::core::raft_core","span":{"name":"apply_to_state_machine"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.737008291Z","level":"DEBUG","message":"about to apply","entries":"[1-0-1001:normal]","target":"openraft::core::raft_core","span":{"name":"apply_to_state_machine"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.737076418Z","level":"DEBUG","message":"sending command to state machine worker: StateMachineCommand { seq: 1002, payload: Apply: [1-0-1001:normal] }","target":"openraft::core::sm","span":{"name":"apply_to_state_machine"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.737160476Z","level":"DEBUG","message":"close","time.busy":"245µs","time.idle":"13.3µs","target":"openraft::core::raft_core","span":{"name":"apply_to_state_machine"},"threadId":"ThreadId(2)"}
operator-node0_1  | {"timestamp":"2023-05-02T03:05:22.737238957Z","level":"DEBUG","message":"close","time.busy":"1.45ms","time.idle":"10.6µs","target":"openraft::core::raft_core","span":{"name":"run_engine_commands"},"threadId":"ThreadId(2)"}

@fredfortier fredfortier reopened this May 2, 2023
@drmingdrmer
Copy link
Member

@fredfortier let me see what's going on there 🤔

@drmingdrmer
Copy link
Member

@fredfortier
To parallel appending-log IO and applying-log IO, applying log entries has been moved from RaftCore task to a separate task sm::Worker, and this worker handles all state-machine IO serialized, including building snapshot. Thus building a snapshot will block applying logs. There is a pending TODO that will fix your issue:

https://github.com/datafuselabs/openraft/blob/80b3c71eab649dff30de89226db07f0b4cc2bfaf/openraft/src/core/sm/mod.rs#L223-L234

I have been careless in introducing this breaking behavior change :(

Let me get this TODO done!

drmingdrmer added a commit to drmingdrmer/openraft that referenced this issue May 2, 2023
Before this commit, snapshot is built in the `sm::Worker`, which blocks
other state-machine writes, such as applying log entries.

This commit parallels applying log entries and building snapshot: A
snapshot is built in another `tokio::task`.

Because building snapshot is a read operation, it does not have to
block the entire state machine. Instead, it only needs a consistent view
of the state machine or holding a lock of the state machine.

- Fix: databendlabs#596
drmingdrmer added a commit to drmingdrmer/openraft that referenced this issue May 2, 2023
Before this commit, snapshot is built in the `sm::Worker`, which blocks
other state-machine writes, such as applying log entries.

This commit parallels applying log entries and building snapshot: A
snapshot is built in another `tokio::task`.

Because building snapshot is a read operation, it does not have to
block the entire state machine. Instead, it only needs a consistent view
of the state machine or holding a lock of the state machine.

- Fix: databendlabs#596
@fredfortier
Copy link
Author

Thanks for the quick turnaround. I understand the root cause as explained. I'll update and re-validate now.

@fredfortier
Copy link
Author

fredfortier commented May 2, 2023

If it's helpful, I can contribute some long running snapshots to your test suite if you give me some pointers (where to put it, etc). That's probably the best way to make our usage quirks benefit the protocol.

In this case, the state machine conditions that the snapshot is waiting for depends on future normal entries, which is why it was deadlocking.

I think your TODO about aborting the snapshot task is important as well. It may be worth considering letting the implementer raise a non-fatal error to either skip the snapshot interval, or retry the snapshot at the last applied log.

@drmingdrmer
Copy link
Member

@fredfortier Let's continue further discussing in this issue:

@fredfortier
Copy link
Author

fredfortier commented May 4, 2023

Regarding this specific issue, your task spawning fixed the issue, but I want to confirm the behavior below is expected:

operator-node0_1  | {"timestamp":"2023-05-04T03:58:08.533751024Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(3)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:09.515947695Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(5)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:10.509952677Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(5)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:11.511494902Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(3)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:12.444429614Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(4)"}

I assume it's multiple tasks because of the different threadId of these events (unless the snapshot_handler tasks just monitor the build_snapshot task).

It does seem to complete properly (not more snapshot_handler message until the next scheduled snapshot):

operator-node0_1  | {"timestamp":"2023-05-04T03:58:51.446988616Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(4)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:51.449027486Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(5)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:51.450275081Z","level":"INFO","message":"openraft::engine::handler::snapshot_handler::SnapshotHandler<_>::trigger_snapshot","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(5)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:51.505529123Z","level":"INFO","message":"close","time.busy":"31.8ms","time.idle":"7.90µs","target":"ddx_core::processor::state","span":{"from":6,"to":7,"name":"advance_epoch"},"threadId":"ThreadId(1)"}
operator-node0_1  | {"timestamp":"2023-05-04T03:58:51.785320007Z","level":"INFO","message":"update_snapshot: SnapshotMeta { last_log_id: Some(LogId { leader_id: LeaderId { term: 1, node_id: 0 }, index: 2407 }), last_membership: StoredMembership { log_id: Some(LogId { leader_id: LeaderId { term: 0, node_id: 0 }, index: 0 }), membership: Membership { configs: [{0}], nodes: {0: OperatorNode { url: \"http://operator-node0:8080/\" }} } }, snapshot_id: \"epoch-6\" }","target":"openraft::engine::handler::snapshot_handler","span":{"name":"init_raft"},"threadId":"ThreadId(4)"}

@drmingdrmer
Copy link
Member

Hmm. This info level log is inappropriate. It should be debug level.

In the function trigger_snapshot it will just return because there is an snapshot building task ongoing.
If it does triggered a building task, it will print another info log at line 37:

https://github.com/datafuselabs/openraft/blob/7ce38e40129357ad1fa9cfa17ecd11e62361281c/openraft/src/engine/handler/snapshot_handler/mod.rs#L28-L43

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants