+6
-6
cmd/domesday/Dockerfile
cmd/bluepages/Dockerfile
+6
-6
cmd/domesday/Dockerfile
cmd/bluepages/Dockerfile
···
1
1
# Run this dockerfile from the top level of the indigo git repository like:
2
2
#
3
-
# podman build -f ./cmd/domesday/Dockerfile -t domesday .
3
+
# podman build -f ./cmd/bluepages/Dockerfile -t bluepages .
4
4
5
5
### Compile stage
6
6
FROM golang:1.23-alpine3.20 AS build-env
···
12
12
# timezone data for alpine builds
13
13
ENV GOEXPERIMENT=loopvar
14
14
RUN GIT_VERSION=$(git describe --tags --long --always) && \
15
-
go build -tags timetzdata -o /domesday ./cmd/domesday
15
+
go build -tags timetzdata -o /bluepages ./cmd/bluepages
16
16
17
17
### Run stage
18
18
FROM alpine:3.20
···
21
21
ENTRYPOINT ["dumb-init", "--"]
22
22
23
23
WORKDIR /
24
-
RUN mkdir -p data/domesday
25
-
COPY --from=build-env /domesday /
24
+
RUN mkdir -p data/bluepages
25
+
COPY --from=build-env /bluepages /
26
26
27
27
# small things to make golang binaries work well under alpine
28
28
ENV GODEBUG=netdns=go
···
30
30
31
31
EXPOSE 2210
32
32
33
-
CMD ["/domesday", "run"]
33
+
CMD ["/bluepages", "run"]
34
34
35
35
LABEL org.opencontainers.image.source=https://github.com/bluesky-social/indigo
36
-
LABEL org.opencontainers.image.description="atproto identity directory (domesday)"
36
+
LABEL org.opencontainers.image.description="atproto identity directory (bluepages)"
37
37
LABEL org.opencontainers.image.licenses=MIT
+1
-3
cmd/domesday/README.md
cmd/bluepages/README.md
+1
-3
cmd/domesday/README.md
cmd/bluepages/README.md
···
1
1
2
-
domesday: an atproto identity directory
2
+
bluepages: an atproto identity directory
3
3
========================================
4
4
5
5
This is a simple API server which caches atproto handle and DID resolution responses. It is useful when you have a bunch of services that do identity resolution, and you don't want duplicated caches.
6
-
7
-
The name is a reference to the [Domesday Book](https://en.wikipedia.org/wiki/Domesday_Book), an early manuscript recoding a English census in 1086. It is a big fancy book with a lot of names in it.
8
6
9
7
Available commands, flags, and config are documented in the usage (`--help`).
10
8
+3
-3
cmd/domesday/firehose.go
cmd/bluepages/firehose.go
+3
-3
cmd/domesday/firehose.go
cmd/bluepages/firehose.go
···
18
18
"github.com/redis/go-redis/v9"
19
19
)
20
20
21
-
var firehoseCursorKey = "domes/firehoseSeq"
21
+
var firehoseCursorKey = "bluepages/firehoseSeq"
22
22
23
23
func (srv *Server) RunFirehoseConsumer(ctx context.Context, host string, parallelism int) error {
24
24
···
38
38
}
39
39
srv.logger.Info("subscribing to repo event stream", "upstream", host, "cursor", cur)
40
40
con, _, err := dialer.Dial(u.String(), http.Header{
41
-
"User-Agent": []string{fmt.Sprintf("domesday/%s", versioninfo.Short())},
41
+
"User-Agent": []string{fmt.Sprintf("bluepages/%s", versioninfo.Short())},
42
42
})
43
43
if err != nil {
44
44
return fmt.Errorf("subscribing to firehose failed (dialing): %w", err)
···
83
83
host,
84
84
rsc.EventHandler,
85
85
)
86
-
srv.logger.Info("domesday firehose scheduler configured", "scheduler", "parallel", "initial", parallelism)
86
+
srv.logger.Info("bluepages firehose scheduler configured", "scheduler", "parallel", "initial", parallelism)
87
87
88
88
return events.HandleRepoStream(ctx, con, scheduler, srv.logger)
89
89
}
+7
-9
cmd/domesday/handlers.go
cmd/bluepages/handlers.go
+7
-9
cmd/domesday/handlers.go
cmd/bluepages/handlers.go
···
236
236
}
237
237
238
238
func (s *Server) HandleHealthCheck(c echo.Context) error {
239
-
return c.JSON(200, GenericStatus{Status: "ok", Daemon: "domesday"})
239
+
return c.JSON(200, GenericStatus{Status: "ok", Daemon: "bluepages"})
240
240
}
241
241
242
242
func (srv *Server) WebHome(c echo.Context) error {
243
243
return c.String(200, `
244
-
######## ####### ## ## ######## ###### ######## ### ## ##
245
-
## ## ## ## ### ### ## ## ## ## ## ## ## ## ##
246
-
## ## ## ## #### #### ## ## ## ## ## ## ####
247
-
## ## ## ## ## ### ## ###### ###### ## ## ## ## ##
248
-
## ## ## ## ## ## ## ## ## ## ######### ##
249
-
## ## ## ## ## ## ## ## ## ## ## ## ## ##
250
-
######## ####### ## ## ######## ###### ######## ## ## ##
244
+
eeeee e e e eeee eeeee eeeee eeeee eeee eeeee
245
+
8 8 8 8 8 8 8 8 8 8 8 8 8 8 "
246
+
8eee8e 8e 8e 8 8eee 8eee8 8eee8 8e 8eee 8eeee
247
+
88 8 88 88 8 88 88 88 8 88 "8 88 88
248
+
88eee8 88eee 88ee8 88ee 88 88 8 88ee8 88ee 8ee88
251
249
252
250
This is an AT Protocol Identity Service
253
251
254
252
Most API routes are under /xrpc/
255
253
256
-
Code: https://github.com/bluesky-social/indigo/tree/main/cmd/domesday
254
+
Code: https://github.com/bluesky-social/indigo/tree/main/cmd/bluepages
257
255
Protocol: https://atproto.com
258
256
`)
259
257
+18
-18
cmd/domesday/main.go
cmd/bluepages/main.go
+18
-18
cmd/domesday/main.go
cmd/bluepages/main.go
···
29
29
func run(args []string) error {
30
30
31
31
app := cli.App{
32
-
Name: "domesday",
32
+
Name: "bluepages",
33
33
Usage: "atproto identity directory",
34
34
Version: versioninfo.Short(),
35
35
Flags: []cli.Flag{
···
49
49
Name: "plc-rate-limit",
50
50
Usage: "max number of requests per second to PLC registry",
51
51
Value: 300,
52
-
EnvVars: []string{"DOMESDAY_PLC_RATE_LIMIT"},
52
+
EnvVars: []string{"BLUEPAGES_PLC_RATE_LIMIT"},
53
53
},
54
54
&cli.StringFlag{
55
55
Name: "redis-url",
56
56
Usage: "redis connection URL: redis://<user>:<pass>@<hostname>:6379/<db>",
57
57
Value: "redis://localhost:6379/0",
58
-
EnvVars: []string{"DOMESDAY_REDIS_URL"},
58
+
EnvVars: []string{"BLUEPAGES_REDIS_URL"},
59
59
},
60
60
&cli.StringFlag{
61
61
Name: "log-level",
62
62
Usage: "log verbosity level (eg: warn, info, debug)",
63
-
EnvVars: []string{"DOMESDAY_LOG_LEVEL", "GO_LOG_LEVEL", "LOG_LEVEL"},
63
+
EnvVars: []string{"BLUEPAGES_LOG_LEVEL", "GO_LOG_LEVEL", "LOG_LEVEL"},
64
64
},
65
65
},
66
66
Commands: []*cli.Command{
67
67
&cli.Command{
68
68
Name: "serve",
69
-
Usage: "run the domesday API daemon",
69
+
Usage: "run the bluepages API daemon",
70
70
Action: runServeCmd,
71
71
Flags: []cli.Flag{
72
72
&cli.StringFlag{
···
74
74
Usage: "Specify the local IP/port to bind to",
75
75
Required: false,
76
76
Value: ":6600",
77
-
EnvVars: []string{"DOMESDAY_BIND"},
77
+
EnvVars: []string{"BLUEPAGES_BIND"},
78
78
},
79
79
&cli.StringFlag{
80
80
Name: "metrics-listen",
81
81
Usage: "IP or address, and port, to listen on for metrics APIs",
82
82
Value: ":3989",
83
-
EnvVars: []string{"DOMESDAY_METRICS_LISTEN"},
83
+
EnvVars: []string{"BLUEPAGES_METRICS_LISTEN"},
84
84
},
85
85
&cli.BoolFlag{
86
86
Name: "disable-firehose-consumer",
87
87
Usage: "don't consume #identity events from firehose",
88
-
EnvVars: []string{"DOMESDAY_DISABLE_FIREHOSE_CONSUMER"},
88
+
EnvVars: []string{"BLUEPAGES_DISABLE_FIREHOSE_CONSUMER"},
89
89
},
90
90
&cli.BoolFlag{
91
91
Name: "disable-refresh",
92
92
Usage: "disable the refreshIdentity API endpoint",
93
-
EnvVars: []string{"DOMESDAY_DISABLE_REFRESH"},
93
+
EnvVars: []string{"BLUEPAGES_DISABLE_REFRESH"},
94
94
},
95
95
&cli.IntFlag{
96
96
Name: "firehose-parallelism",
97
97
Usage: "number of concurrent firehose workers",
98
98
Value: 4,
99
-
EnvVars: []string{"DOMESDAY_FIREHOSE_PARALLELISM"},
99
+
EnvVars: []string{"BLUEPAGES_FIREHOSE_PARALLELISM"},
100
100
},
101
101
},
102
102
},
···
108
108
Flags: []cli.Flag{
109
109
&cli.StringFlag{
110
110
Name: "host",
111
-
Usage: "domesday server to send request to",
111
+
Usage: "bluepages server to send request to",
112
112
Value: "http://localhost:6600",
113
-
EnvVars: []string{"DOMESDAY_HOST"},
113
+
EnvVars: []string{"BLUEPAGES_HOST"},
114
114
},
115
115
},
116
116
},
···
122
122
Flags: []cli.Flag{
123
123
&cli.StringFlag{
124
124
Name: "host",
125
-
Usage: "domesday server to send request to",
125
+
Usage: "bluepages server to send request to",
126
126
Value: "http://localhost:6600",
127
-
EnvVars: []string{"DOMESDAY_HOST"},
127
+
EnvVars: []string{"BLUEPAGES_HOST"},
128
128
},
129
129
},
130
130
},
···
136
136
Flags: []cli.Flag{
137
137
&cli.StringFlag{
138
138
Name: "host",
139
-
Usage: "domesday server to send request to",
139
+
Usage: "bluepages server to send request to",
140
140
Value: "http://localhost:6600",
141
-
EnvVars: []string{"DOMESDAY_HOST"},
141
+
EnvVars: []string{"BLUEPAGES_HOST"},
142
142
},
143
143
},
144
144
},
···
150
150
Flags: []cli.Flag{
151
151
&cli.StringFlag{
152
152
Name: "host",
153
-
Usage: "domesday server to send request to",
153
+
Usage: "bluepages server to send request to",
154
154
Value: "http://localhost:6600",
155
-
EnvVars: []string{"DOMESDAY_HOST"},
155
+
EnvVars: []string{"BLUEPAGES_HOST"},
156
156
},
157
157
},
158
158
},
+10
-10
cmd/domesday/metrics.go
cmd/bluepages/metrics.go
+10
-10
cmd/domesday/metrics.go
cmd/bluepages/metrics.go
···
6
6
)
7
7
8
8
var handleCacheHits = promauto.NewCounter(prometheus.CounterOpts{
9
-
Name: "domesday_resolve_handle_cache_hits",
9
+
Name: "bluepages_resolve_handle_cache_hits",
10
10
Help: "Number of cache hits for ATProto handle resolutions",
11
11
})
12
12
13
13
var handleCacheMisses = promauto.NewCounter(prometheus.CounterOpts{
14
-
Name: "domesday_resolve_handle_cache_misses",
14
+
Name: "bluepages_resolve_handle_cache_misses",
15
15
Help: "Number of cache misses for ATProto handle resolutions",
16
16
})
17
17
18
18
var handleRequestsCoalesced = promauto.NewCounter(prometheus.CounterOpts{
19
-
Name: "domesday_resolve_handle_requests_coalesced",
19
+
Name: "bluepages_resolve_handle_requests_coalesced",
20
20
Help: "Number of handle requests coalesced",
21
21
})
22
22
23
23
var handleResolutionErrors = promauto.NewCounter(prometheus.CounterOpts{
24
-
Name: "domesday_resolve_handle_resolution_errors",
24
+
Name: "bluepages_resolve_handle_resolution_errors",
25
25
Help: "Number of non-cached handle resolution errors",
26
26
})
27
27
28
28
var handleResolveDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
29
-
Name: "domesday_resolve_handle_duration",
29
+
Name: "bluepages_resolve_handle_duration",
30
30
Help: "Time to resolve a handle from network (not cached)",
31
31
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
32
32
}, []string{"status"})
33
33
34
34
var didCacheHits = promauto.NewCounter(prometheus.CounterOpts{
35
-
Name: "domesday_resolve_did_cache_hits",
35
+
Name: "bluepages_resolve_did_cache_hits",
36
36
Help: "Number of cache hits for ATProto DID resolutions",
37
37
})
38
38
39
39
var didCacheMisses = promauto.NewCounter(prometheus.CounterOpts{
40
-
Name: "domesday_resolve_did_cache_misses",
40
+
Name: "bluepages_resolve_did_cache_misses",
41
41
Help: "Number of cache misses for ATProto DID resolutions",
42
42
})
43
43
44
44
var didRequestsCoalesced = promauto.NewCounter(prometheus.CounterOpts{
45
-
Name: "domesday_resolve_did_requests_coalesced",
45
+
Name: "bluepages_resolve_did_requests_coalesced",
46
46
Help: "Number of DID requests coalesced",
47
47
})
48
48
49
49
var didResolutionErrors = promauto.NewCounter(prometheus.CounterOpts{
50
-
Name: "domesday_resolve_did_resolution_errors",
50
+
Name: "bluepages_resolve_did_resolution_errors",
51
51
Help: "Number of non-cached DID resolution errors",
52
52
})
53
53
54
54
var didResolveDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
55
-
Name: "domesday_resolve_did_duration",
55
+
Name: "bluepages_resolve_did_duration",
56
56
Help: "Time to resolve a DID from network (not cached)",
57
57
Buckets: prometheus.ExponentialBucketsRange(0.001, 2, 15),
58
58
}, []string{"status"})
+8
-8
cmd/domesday/resolver.go
cmd/bluepages/resolver.go
+8
-8
cmd/domesday/resolver.go
cmd/bluepages/resolver.go
···
122
122
}
123
123
err = d.handleCache.Set(&cache.Item{
124
124
Ctx: ctx,
125
-
Key: "domes/handle/" + h.String(),
125
+
Key: "bluepages/handle/" + h.String(),
126
126
Value: he,
127
127
TTL: d.ErrTTL,
128
128
})
···
157
157
158
158
err = d.didCache.Set(&cache.Item{
159
159
Ctx: ctx,
160
-
Key: "domes/did/" + did.String(),
160
+
Key: "bluepages/did/" + did.String(),
161
161
Value: entry,
162
162
TTL: d.HitTTL,
163
163
})
···
173
173
}
174
174
h = h.Normalize()
175
175
var entry handleEntry
176
-
err := d.handleCache.Get(ctx, "domes/handle/"+h.String(), &entry)
176
+
err := d.handleCache.Get(ctx, "bluepages/handle/"+h.String(), &entry)
177
177
if err != nil && err != cache.ErrCacheMiss {
178
178
return "", fmt.Errorf("identity cache read failed: %w", err)
179
179
}
···
198
198
select {
199
199
case <-val.(chan struct{}):
200
200
// The result should now be in the cache
201
-
err := d.handleCache.Get(ctx, "domes/handle/"+h.String(), entry)
201
+
err := d.handleCache.Get(ctx, "bluepages/handle/"+h.String(), entry)
202
202
if err != nil && err != cache.ErrCacheMiss {
203
203
return "", fmt.Errorf("identity cache read failed: %w", err)
204
204
}
···
236
236
237
237
func (d *RedisResolver) ResolveDIDRaw(ctx context.Context, did syntax.DID) (json.RawMessage, error) {
238
238
var entry didEntry
239
-
err := d.didCache.Get(ctx, "domes/did/"+did.String(), &entry)
239
+
err := d.didCache.Get(ctx, "bluepages/did/"+did.String(), &entry)
240
240
if err != nil && err != cache.ErrCacheMiss {
241
241
return nil, fmt.Errorf("DID cache read failed: %w", err)
242
242
}
···
255
255
select {
256
256
case <-val.(chan struct{}):
257
257
// The result should now be in the cache
258
-
err = d.didCache.Get(ctx, "domes/did/"+did.String(), &entry)
258
+
err = d.didCache.Get(ctx, "bluepages/did/"+did.String(), &entry)
259
259
if err != nil && err != cache.ErrCacheMiss {
260
260
return nil, fmt.Errorf("DID cache read failed: %w", err)
261
261
}
···
303
303
304
304
func (d *RedisResolver) PurgeHandle(ctx context.Context, handle syntax.Handle) error {
305
305
handle = handle.Normalize()
306
-
err := d.handleCache.Delete(ctx, "domes/handle/"+handle.String())
306
+
err := d.handleCache.Delete(ctx, "bluepages/handle/"+handle.String())
307
307
if err == cache.ErrCacheMiss {
308
308
return nil
309
309
}
···
311
311
}
312
312
313
313
func (d *RedisResolver) PurgeDID(ctx context.Context, did syntax.DID) error {
314
-
err := d.didCache.Delete(ctx, "domes/did/"+did.String())
314
+
err := d.didCache.Delete(ctx, "bluepages/did/"+did.String())
315
315
if err == cache.ErrCacheMiss {
316
316
return nil
317
317
}
+2
-2
cmd/domesday/server.go
cmd/bluepages/server.go
+2
-2
cmd/domesday/server.go
cmd/bluepages/server.go
···
74
74
PLCLimiter: rate.NewLimiter(rate.Limit(config.PLCRateLimit), 1),
75
75
TryAuthoritativeDNS: true,
76
76
SkipDNSDomainSuffixes: []string{".bsky.social", ".staging.bsky.dev"},
77
-
// TODO: UserAgent: "domesday",
77
+
// TODO: UserAgent: "bluepages",
78
78
}
79
79
80
80
// TODO: config these timeouts
···
210
210
errorMessage = fmt.Sprintf("%s", he.Message)
211
211
}
212
212
if code >= 500 {
213
-
srv.logger.Warn("domesday-http-internal-error", "err", err)
213
+
srv.logger.Warn("bluepages-http-internal-error", "err", err)
214
214
}
215
215
if !c.Response().Committed {
216
216
c.JSON(code, GenericError{Error: "InternalError", Message: errorMessage})