-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnostr.go
135 lines (121 loc) · 2.63 KB
/
nostr.go
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package nin
import (
"context"
"sync"
sdk "github.com/nbd-wtf/go-nostr"
)
type Engine struct {
IRoutes
relay *sdk.Relay
opt *Options
noRoute HandlersChain
pool sync.Pool
filters chan sdk.Filters
}
type HandlerFunc func(*Context) error
type HandlersChain []HandlerFunc
// Last returns the last handler in the chain. i.e. the last handler is the main one.
func (c HandlersChain) Last() HandlerFunc {
if length := len(c); length > 0 {
return c[length-1]
}
return nil
}
func New(opt *Options) (*Engine, error) {
debugPrintWARNINGNew()
if err := opt.init(); err != nil {
return nil, err
}
relay, err := sdk.RelayConnect(context.Background(), opt.URL())
if err != nil {
return nil, err
}
r := &Router{}
r.ctx, r.cancel = context.WithCancel(context.Background())
engine := &Engine{
IRoutes: r,
relay: relay,
opt: opt,
filters: make(chan sdk.Filters, 1),
}
engine.pool.New = func() interface{} {
return engine.allocateContext()
}
return engine, nil
}
func Default(opt *Options) (*Engine, error) {
engine, err := New(opt)
if err != nil {
return nil, err
}
engine.Use(Logger(), Recovery())
return engine, nil
}
func (e *Engine) ResetFilters(f sdk.Filters) {
e.filters <- f
}
func (e *Engine) Run() error {
debugPrint(`[DEBUG] Now Nin started and waiting for events...`)
sub, err := e.relay.Subscribe(context.Background(), e.opt.Filters)
if err != nil {
return err
}
e.subEvents(sub)
return nil
}
func (e *Engine) restart() {
debugPrint(`[DEBUG] Now Nin restarted and waiting for events...`)
//e.relay.Close()
sub, _ := e.relay.Subscribe(context.Background(), e.opt.Filters)
e.subEvents(sub)
}
func (e *Engine) subEvents(sub *sdk.Subscription) {
for {
select {
case event := <-sub.Events:
if err := e.handle(event); err != nil {
e.opt.ErrFun(err)
}
case filters := <-e.filters:
e.opt.Filters = filters
e.restart()
return
}
}
}
func (e *Engine) allocateContext() *Context {
return &Context{}
}
func (e *Engine) handle(event *sdk.Event) error {
c := e.pool.Get().(*Context)
defer func() {
c.reset()
e.pool.Put(c)
}()
action, err := parseTags(event.Tags)
if err != nil {
return err
}
action.SetE(event.ID)
action.SetP(event.PubKey)
path, err := action.path()
if err != nil {
return err
}
c.Writer = e.relay
c.PrivateKey = e.opt.PrivateKey
c.SelfPublicKey = e.opt.publicKey
c.PublicKey = event.PubKey
c.Path = path
handles, ok := e.IRoutes.Handlers()[path]
if !ok {
return ErrPathNotFound(path)
}
c.Handlers = handles
c.index = -1
c.Action = action
c.Event = event
c.Status = sdk.PublishStatusFailed
c.ctx = context.Background()
return c.Next()
}