feat: support durable task cancellation without foreign keys
This commit is contained in:
@@ -98,6 +98,15 @@ func (s *ExecutionStore) Connect(ctx context.Context, token auth.Token, in worke
|
||||
if registration != storedRegistration || epoch == ^uint64(0) {
|
||||
return fault.Conflict
|
||||
}
|
||||
// 不依赖数据库外键:创建会话前验证队列存在且属于当前命名空间。
|
||||
// 进程头在队列之前加锁,与执行命令保持一致;失败时回滚新建的进程头。
|
||||
var queue core.ID
|
||||
if err := tx.QueryRowContext(ctx, `SELECT id FROM pulse_queues WHERE namespace_id=? AND id=? FOR SHARE`, token.NamespaceID, in.QueueID).Scan(&queue); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return fault.NotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
now, err := dbNow(ctx, tx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -160,9 +169,13 @@ func (s *ExecutionStore) lockSession(ctx context.Context, tx *sql.Tx, token auth
|
||||
if !p.AllowsQueue(state.queue) {
|
||||
return state, fault.Forbidden
|
||||
}
|
||||
var node core.ID
|
||||
var node, instance, sessionCredential core.ID
|
||||
var sessionEpoch uint64
|
||||
var raw []byte
|
||||
err = tx.QueryRowContext(ctx, `SELECT node_id,capacity,capacity_sequence,capabilities,expires_at FROM pulse_worker_sessions WHERE namespace_id=? AND id=? FOR UPDATE`, token.NamespaceID, b.SessionID).Scan(&node, &state.capacity, &state.sequence, &raw, &state.expires)
|
||||
err = tx.QueryRowContext(ctx, `SELECT node_id,worker_instance_id,credential_id,session_epoch,capacity,capacity_sequence,capabilities,expires_at FROM pulse_worker_sessions WHERE namespace_id=? AND id=? FOR UPDATE`, token.NamespaceID, b.SessionID).Scan(&node, &instance, &sessionCredential, &sessionEpoch, &state.capacity, &state.sequence, &raw, &state.expires)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return state, worker.StaleSession
|
||||
}
|
||||
if err != nil {
|
||||
return state, err
|
||||
}
|
||||
@@ -170,7 +183,7 @@ func (s *ExecutionStore) lockSession(ctx context.Context, tx *sql.Tx, token auth
|
||||
if err != nil {
|
||||
return state, err
|
||||
}
|
||||
if node != s.node || !state.expires.After(now) {
|
||||
if node != s.node || instance != b.InstanceID || sessionCredential != token.CredentialID || sessionEpoch != b.Epoch || !state.expires.After(now) {
|
||||
return state, worker.StaleSession
|
||||
}
|
||||
if err := json.Unmarshal(raw, &state.capabilities); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user