Repository navigation
Expand file tree
/
Copy pathreader.go
More file actions
92 lines (86 loc) · 2.36 KB
/
Copy pathreader.go
File metadata and controls
92 lines (86 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package whitewater
import "context"
// ReaderSessionClient is one named Reader: open/fetch/ack/close with a
// durable cursor. Delivery is at-least-once; ack a page's delivered
// cursor to commit progress.
type ReaderSessionClient struct {
transport *transport
reader string
}
// Open resumes the Reader's durable cursor under a new session epoch.
func (r *ReaderSessionClient) Open(
ctx context.Context, capacity int,
) (ReaderSession, error) {
raw, err := r.transport.post(ctx, "/v1/readers/open", map[string]any{
"request_id": newUUID(),
"reader": r.reader,
"capacity": capacity,
})
if err != nil {
return ReaderSession{}, err
}
body, err := decodeBody(raw)
if err != nil {
return ReaderSession{}, err
}
return decodeReaderSession(body), nil
}
// Fetch returns up to limit records after the delivered cursor.
func (r *ReaderSessionClient) Fetch(
ctx context.Context, session ReaderSession, limit int,
) (ReaderPage, error) {
body := map[string]any{
"request_id": newUUID(),
"reader": r.reader,
"session_epoch": session.SessionEpoch,
}
if limit > 0 {
body["limit"] = limit
}
raw, err := r.transport.post(ctx, "/v1/readers/fetch", body)
if err != nil {
return ReaderPage{}, err
}
decoded, err := decodeBody(raw)
if err != nil {
return ReaderPage{}, err
}
return decodeReaderPage(decoded), nil
}
// Ack durably commits progress at a page's delivered cursor.
func (r *ReaderSessionClient) Ack(
ctx context.Context, session ReaderSession, cursor Cursor,
) (ReaderSession, error) {
raw, err := r.transport.post(ctx, "/v1/readers/ack", map[string]any{
"request_id": newUUID(),
"reader": r.reader,
"session_epoch": session.SessionEpoch,
"cursor": string(cursor),
})
if err != nil {
return ReaderSession{}, err
}
body, err := decodeBody(raw)
if err != nil {
return ReaderSession{}, err
}
return decodeReaderSession(body), nil
}
// Close ends the session epoch.
func (r *ReaderSessionClient) Close(
ctx context.Context, session ReaderSession,
) (ReaderSession, error) {
raw, err := r.transport.post(ctx, "/v1/readers/close", map[string]any{
"request_id": newUUID(),
"reader": r.reader,
"session_epoch": session.SessionEpoch,
})
if err != nil {
return ReaderSession{}, err
}
body, err := decodeBody(raw)
if err != nil {
return ReaderSession{}, err
}
return decodeReaderSession(body), nil
}