feat: publish standalone worker
Separate worker packaging and service lifecycle from the control plane.
Этот коммит содержится в:
152
internal/workercluster/entries.go
Обычный файл
152
internal/workercluster/entries.go
Обычный файл
@@ -0,0 +1,152 @@
|
||||
package workercluster
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// EntryType enumerates the kinds of replicated log entries the FSM
|
||||
// understands. Every log entry committed through the Raft Apply path
|
||||
// carries an Entry of one of these kinds.
|
||||
//
|
||||
// The set is the subset from plan section 6.2 that this implementation
|
||||
// actually exercises today. The remaining kinds are defined in
|
||||
// distworker/entries.go placeholders (ObserverSetUpdate, IncidentObserve,
|
||||
// ...) so later phases can add Apply branches without a wire-format
|
||||
// churn.
|
||||
type EntryType string
|
||||
|
||||
const (
|
||||
// EntryConfigAdopt installs a new adopted critical-check list
|
||||
// into the FSM. Replaces any previously adopted list.
|
||||
EntryConfigAdopt EntryType = "config.adopt"
|
||||
|
||||
// EntryObserverSetUpdate installs a new observer set with a
|
||||
// version stamp.
|
||||
EntryObserverSetUpdate EntryType = "observer_set.update"
|
||||
|
||||
// EntryMembershipProposeAdd appends a Member to the membership
|
||||
// cache. The Raft library itself handles the voter promotion; the
|
||||
// FSM just keeps a denormalized mirror.
|
||||
EntryMembershipProposeAdd EntryType = "membership.propose_add"
|
||||
|
||||
// EntryMembershipDemote flips a voter's role to observer.
|
||||
EntryMembershipDemote EntryType = "membership.demote"
|
||||
|
||||
// EntryMembershipRemove drops a Member from the membership cache.
|
||||
EntryMembershipRemove EntryType = "membership.remove"
|
||||
|
||||
// EntryIncidentObserve appends one observer vote for a check.
|
||||
EntryIncidentObserve EntryType = "incident.observe"
|
||||
|
||||
// EntryIncidentTransition records a state transition produced by
|
||||
// the FSM from committed observations.
|
||||
EntryIncidentTransition EntryType = "incident.transition"
|
||||
|
||||
// EntryOutboxEnqueue appends notification outbox metadata.
|
||||
EntryOutboxEnqueue EntryType = "outbox.enqueue"
|
||||
|
||||
// EntryOutboxDelivered marks an outbox entry as delivered.
|
||||
EntryOutboxDelivered EntryType = "outbox.delivered"
|
||||
|
||||
// EntryOutboxAck records a delivery ack / duplicate marker.
|
||||
EntryOutboxAck EntryType = "outbox.ack"
|
||||
|
||||
// EntryPartitionReport stores the cluster's view of network
|
||||
// partition state.
|
||||
EntryPartitionReport EntryType = "partition.report"
|
||||
|
||||
// EntryDiagnosticsUpdate stores per-worker health metadata.
|
||||
EntryDiagnosticsUpdate EntryType = "diagnostics.update"
|
||||
)
|
||||
|
||||
// Entry is the wire format the FSM expects on every Apply. The Data
|
||||
// field holds the JSON-encoded payload of the matching struct.
|
||||
type Entry struct {
|
||||
Type EntryType `json:"type"`
|
||||
Term uint64 `json:"term,omitempty"`
|
||||
Index uint64 `json:"index,omitempty"`
|
||||
ActorID string `json:"actor_id,omitempty"`
|
||||
Version uint64 `json:"version,omitempty"`
|
||||
Adopted json.RawMessage `json:"adopted,omitempty"`
|
||||
Set json.RawMessage `json:"set,omitempty"`
|
||||
Member json.RawMessage `json:"member,omitempty"`
|
||||
State json.RawMessage `json:"state,omitempty"`
|
||||
Observe json.RawMessage `json:"observe,omitempty"`
|
||||
Outbox json.RawMessage `json:"outbox,omitempty"`
|
||||
OutboxID uint64 `json:"outbox_seq,omitempty"`
|
||||
Report json.RawMessage `json:"report,omitempty"`
|
||||
Diag json.RawMessage `json:"diag,omitempty"`
|
||||
}
|
||||
|
||||
// ConfigAdoptPayload is the body of an EntryConfigAdopt entry.
|
||||
type ConfigAdoptPayload struct {
|
||||
Version uint64 `json:"version"`
|
||||
Actor string `json:"actor"`
|
||||
Checks []CriticalCheckConfig `json:"checks"`
|
||||
}
|
||||
|
||||
// ObserverSetPayload is the body of an EntryObserverSetUpdate entry.
|
||||
type ObserverSetPayload struct {
|
||||
Set ObserverSet `json:"set"`
|
||||
}
|
||||
|
||||
// MemberPayload is the body of an EntryMembershipProposeAdd,
|
||||
// EntryMembershipDemote, and EntryMembershipRemove entries.
|
||||
type MemberPayload struct {
|
||||
Member Member `json:"member"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Prev *Member `json:"prev,omitempty"` // populated on demote/remove
|
||||
}
|
||||
|
||||
// IncidentObservePayload is one observer vote for a check.
|
||||
type IncidentObservePayload struct {
|
||||
CheckID int64 `json:"check_id"`
|
||||
WorkerID string `json:"worker_id"`
|
||||
Label string `json:"label"` // ok | warn | down | unknown
|
||||
ObservedIx uint64 `json:"observed_at_index"`
|
||||
}
|
||||
|
||||
// IncidentTransitionPayload is the FSM-produced state transition
|
||||
// recorded after a quorum rule fires.
|
||||
type IncidentTransitionPayload struct {
|
||||
CheckID int64 `json:"check_id"`
|
||||
State IncidentState `json:"state"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
}
|
||||
|
||||
// OutboxPayload is the body of an EntryOutboxEnqueue entry.
|
||||
type OutboxPayload struct {
|
||||
Entry OutboxMeta `json:"entry"`
|
||||
}
|
||||
|
||||
// OutboxUpdatePayload is the body of EntryOutboxDelivered and
|
||||
// EntryOutboxAck entries.
|
||||
type OutboxUpdatePayload struct {
|
||||
Seq uint64 `json:"seq"`
|
||||
State string `json:"state"`
|
||||
Attempts int `json:"attempts"`
|
||||
LastError string `json:"last_error,omitempty"`
|
||||
}
|
||||
|
||||
// PartitionReportPayload is the body of an EntryPartitionReport entry.
|
||||
type PartitionReportPayload struct {
|
||||
State PartitionState `json:"state"`
|
||||
}
|
||||
|
||||
// DiagnosticsPayload is the body of an EntryDiagnosticsUpdate entry.
|
||||
type DiagnosticsPayload struct {
|
||||
Diag WorkerDiagnostics `json:"diag"`
|
||||
}
|
||||
|
||||
// EncodeEntry marshals a fully-populated Entry to JSON bytes ready to
|
||||
// hand to raft.Apply.
|
||||
func EncodeEntry(e *Entry) ([]byte, error) {
|
||||
return json.Marshal(e)
|
||||
}
|
||||
|
||||
// DecodeEntry parses Entry bytes back into the wire struct.
|
||||
func DecodeEntry(b []byte) (Entry, error) {
|
||||
var e Entry
|
||||
if err := json.Unmarshal(b, &e); err != nil {
|
||||
return e, err
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
Ссылка в новой задаче
Block a user