@@ -11,17 +11,17 @@ import (
11
11
12
12
type processor struct {
13
13
sync.RWMutex
14
- subs []reactor.Subscriber
15
- stat int32
16
- v Any
14
+ subscriber reactor.Subscriber
15
+ stat int32
16
+ requested int32
17
+ v Any
17
18
}
18
19
19
20
type processorSubscriber struct {
20
- parent * processor
21
- actual reactor.Subscriber
22
- stat int32
23
- s reactor.Subscription
24
- requested int32
21
+ parent * processor
22
+ actual reactor.Subscriber
23
+ stat int32
24
+ s reactor.Subscription
25
25
}
26
26
27
27
func (p * processor ) getValue () Any {
@@ -36,26 +36,27 @@ func (p *processor) setValue(v Any) {
36
36
p .v = v
37
37
}
38
38
39
- func (p * processor ) getStat () (stat int32 ) {
40
- return atomic .LoadInt32 (& p .stat )
41
- }
42
-
43
39
func (p * processor ) Success (v Any ) {
44
40
if ! atomic .CompareAndSwapInt32 (& p .stat , 0 , statComplete ) {
45
41
hooks .Global ().OnNextDrop (v )
46
42
return
47
43
}
48
44
49
- p .setValue (v )
50
-
51
45
p .RLock ()
52
- defer p .RUnlock ()
53
- for i , l := 0 , len (p .subs ); i < l ; i ++ {
54
- s := p .subs [i ]
46
+ if p .subscriber == nil {
47
+ p .RUnlock ()
48
+ p .setValue (v )
49
+ return
50
+ }
51
+ p .RUnlock ()
52
+
53
+ if atomic .LoadInt32 (& p .requested ) > 0 {
55
54
if v != nil {
56
- s .OnNext (v )
55
+ p . subscriber .OnNext (v )
57
56
}
58
- s .OnComplete ()
57
+ p .subscriber .OnComplete ()
58
+ } else {
59
+ p .setValue (v )
59
60
}
60
61
}
61
62
@@ -64,11 +65,18 @@ func (p *processor) Error(e error) {
64
65
hooks .Global ().OnErrorDrop (e )
65
66
return
66
67
}
67
- p . setValue ( e )
68
+
68
69
p .RLock ()
69
- defer p .RUnlock ()
70
- for i , l := 0 , len (p .subs ); i < l ; i ++ {
71
- p .subs [i ].OnError (e )
70
+ if p .subscriber == nil {
71
+ p .RUnlock ()
72
+ p .setValue (e )
73
+ return
74
+ }
75
+
76
+ if atomic .LoadInt32 (& p .requested ) > 0 {
77
+ p .subscriber .OnError (e )
78
+ } else {
79
+ p .setValue (e )
72
80
}
73
81
}
74
82
@@ -77,33 +85,45 @@ func (p *processor) SubscribeWith(ctx context.Context, s reactor.Subscriber) {
77
85
case <- ctx .Done ():
78
86
s .OnError (reactor .ErrSubscribeCancelled )
79
87
default :
88
+ p .Lock ()
89
+ if p .subscriber != nil {
90
+ p .Unlock ()
91
+ panic ("reactor: mono processor can only been subscribed once!" )
92
+ }
93
+ p .subscriber = s
94
+ p .Unlock ()
80
95
s .OnSubscribe (ctx , & processorSubscriber {
81
96
actual : s ,
82
97
parent : p ,
83
98
})
84
- p .Lock ()
85
- p .subs = append (p .subs , s )
86
- p .Unlock ()
87
99
}
88
100
}
89
101
102
+ func (p * processor ) getStat () (stat int32 ) {
103
+ return atomic .LoadInt32 (& p .stat )
104
+ }
105
+
90
106
func (p * processorSubscriber ) Request (n int ) {
91
107
if n < 1 {
92
108
panic (reactor .ErrNegativeRequest )
93
109
}
94
- if atomic .AddInt32 (& p .requested , 1 ) != 1 {
110
+
111
+ if atomic .AddInt32 (& p .parent .requested , 1 ) != 1 {
95
112
return
96
113
}
97
- v := p . parent . getValue ()
114
+
98
115
switch p .parent .getStat () {
99
116
case statError :
117
+ v := p .parent .getValue ()
100
118
p .OnError (v .(error ))
101
119
case statComplete :
120
+ v := p .parent .getValue ()
102
121
if v != nil {
103
122
p .OnNext (v )
104
123
}
105
124
p .OnComplete ()
106
125
}
126
+
107
127
}
108
128
109
129
func (p * processorSubscriber ) Cancel () {
0 commit comments