Lasa is a stateless proxy that generates a RSS or an Atom feed from a Standard.site publication.
lasa.anhgelus.world
rss
atom
atprotocol
standard-site
atproto
1package lasa
2
3import (
4 "sync"
5 "sync/atomic"
6)
7
8type limitRequests[T any] struct {
9 n atomic.Uint32
10 ch chan T
11}
12
13func newLimitRequests[T any]() *limitRequests[T] {
14 return &limitRequests[T]{ch: make(chan T)}
15}
16
17func (l *limitRequests[T]) Sub() T {
18 l.n.Add(1)
19 return <-l.ch
20}
21
22func (l *limitRequests[T]) Send(v T) {
23 for range l.n.Load() {
24 l.ch <- v
25 }
26}
27
28type LimitManyRequests[T any] struct {
29 content map[string]*limitRequests[T]
30 mu sync.RWMutex
31}
32
33func NewLimitManyRequests[T any]() *LimitManyRequests[T] {
34 return &LimitManyRequests[T]{content: make(map[string]*limitRequests[T])}
35}
36
37func (lm *LimitManyRequests[T]) Do(key string, fn func() (T, error)) (T, error) {
38 lm.mu.RLock()
39 l, ok := lm.content[key]
40 if ok {
41 lm.mu.RUnlock()
42 return l.Sub(), nil
43 }
44 lm.mu.RUnlock()
45
46 l = newLimitRequests[T]()
47 lm.mu.Lock()
48 lm.content[key] = l
49 lm.mu.Unlock()
50
51 defer func() {
52 lm.mu.Lock()
53 delete(lm.content, key)
54 lm.mu.Unlock()
55 }()
56
57 v, err := fn()
58 if err != nil {
59 return v, err
60 }
61 l.Send(v)
62 return v, nil
63}