Documentation
¶
Overview ¶
Package outbox holds the ticket writes that have not reached the remote yet.
It exists because of a decision about how the tool should feel: claiming a ticket works offline. Being offline is rare enough that it must not dictate the interaction — so a claim is written locally straight away and the push is caught up when there is a network again. Something has to hold the write in between, and that is this.
It also settles a problem that would otherwise sit in the write path. Every ticket write funnels through core/ticket's Mutate and Create, and those are called from the TUI and from the merge driver as well as from the CLI. A synchronous push there would hang the board on the network and would have the merge driver pushing in the middle of a git merge. With an outbox, the write path only files the write; sending happens outside it.
The outbox lives under the per-working-tree state directory, not in the repository: an unsent write is this machine's business, and committing it would publish it in the very moment it is meant to be waiting.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Box ¶
type Box struct{ Dir string }
Box is the queue for one working tree.
func (*Box) Flush ¶
Flush sends what it can and reports each entry.
It stops at the first unreachable remote instead of walking the rest of the queue. The network is a property of the machine, not of the ticket: once one push has proved there is no route, every following attempt would wait for the same timeout, and a command the user ran for another reason entirely would sit there for as long as the queue is.
A lost race is the opposite case and does not stop anything: it is about one ticket, and the next one may well go through.
func (*Box) List ¶
List returns every unsent write, oldest first. Ticket ids are ULIDs, so sorting by id is chronological by creation; QueuedAt orders by when the write was filed, which is what a flush should follow.
func (*Box) Pending ¶
Pending returns the unsent write for one ticket, if there is one. The board asks this to mark a card as carrying something not yet sent.
type Entry ¶
type Entry struct {
ID string `json:"id"`
Op Op `json:"op"`
Ref string `json:"ref"`
// Lease is the ref SHA the remote last confirmed to us, and it is the
// compare-and-swap value. It survives being superseded: a second local
// write while the first is still unsent replaces the content but keeps
// this, because the question the remote answers is "has anyone written
// since I last saw it", and our own unsent write is not an answer to that.
Lease string `json:"lease"`
// Content is the whole ticket file, not a patch. The file is the API, and
// a queued write that replayed a diff could apply cleanly onto a state
// nobody ever reviewed.
Content string `json:"content,omitempty"`
QueuedAt time.Time `json:"queued-at"`
UpdatedAt time.Time `json:"updated-at"`
By string `json:"by,omitempty"`
}
Entry is one ticket's pending write.
type Outcome ¶
type Outcome string
Outcome is what became of one queued write during a flush.
const ( // Sent means the remote accepted it and the entry is gone. Sent Outcome = "sent" // Rejected means someone else wrote the ticket first. The entry is // dropped: replaying it would only lose again, and the local file is still // there for the board to merge the ref into. Rejected Outcome = "rejected" // Unsent means the remote could not be reached. The entry stays. Unsent Outcome = "unsent" // Failed means git refused for some other reason. The entry stays, because // the cause is unknown and discarding a write on an unknown error is the // one outcome that loses work. Failed Outcome = "failed" )
type Sender ¶
type Sender interface {
Write(id string, content []byte, lease string) (string, error)
Delete(id, lease string) error
}
Sender is the transport a flush pushes through. It is an interface so the queue's behaviour — what it keeps, what it drops, when it stops — can be tested without a remote, and so nothing in here depends on a network being reachable.