55	"fmt" 
66	"io" 
77	"net/http" 
8- 	"reflect" 
98	"strings" 
109	"sync" 
1110	"time" 
@@ -26,9 +25,9 @@ type Monitor struct {
2625	url  string 
2726
2827	applied        chan  []* Applied 
29- 	refused        chan  []* Applied 
30- 	branchDelayed  chan  []* Applied 
31- 	branchRefused  chan  []* Applied 
28+ 	refused        chan  []* FailedMonitor 
29+ 	branchDelayed  chan  []* FailedMonitor 
30+ 	branchRefused  chan  []* FailedMonitor 
3231
3332	subscribedOnApplied        bool 
3433	subscribedOnRefused        bool 
@@ -43,9 +42,9 @@ func NewMonitor(url string) *Monitor {
4342	return  & Monitor {
4443		url :           strings .TrimSuffix (url , "/" ),
4544		applied :       make (chan  []* Applied , 4096 ),
46- 		refused :       make (chan  []* Applied , 4096 ),
47- 		branchDelayed : make (chan  []* Applied , 4096 ),
48- 		branchRefused : make (chan  []* Applied , 4096 ),
45+ 		refused :       make (chan  []* FailedMonitor , 4096 ),
46+ 		branchDelayed : make (chan  []* FailedMonitor , 4096 ),
47+ 		branchRefused : make (chan  []* FailedMonitor , 4096 ),
4948	}
5049}
5150
@@ -109,17 +108,17 @@ func (monitor *Monitor) Applied() <-chan []*Applied {
109108}
110109
111110// BranchRefused - 
112- func  (monitor  * Monitor ) BranchRefused () <- chan  []* Applied  {
111+ func  (monitor  * Monitor ) BranchRefused () <- chan  []* FailedMonitor  {
113112	return  monitor .branchRefused 
114113}
115114
116115// BranchDelayed - 
117- func  (monitor  * Monitor ) BranchDelayed () <- chan  []* Applied  {
116+ func  (monitor  * Monitor ) BranchDelayed () <- chan  []* FailedMonitor  {
118117	return  monitor .branchDelayed 
119118}
120119
121120// Refused - 
122- func  (monitor  * Monitor ) Refused () <- chan  []* Applied  {
121+ func  (monitor  * Monitor ) Refused () <- chan  []* FailedMonitor  {
123122	return  monitor .refused 
124123}
125124
@@ -137,35 +136,31 @@ func (monitor *Monitor) pollingMempool(ctx context.Context, filter string) {
137136		case  <- ctx .Done ():
138137			return 
139138		default :
140- 			ch , err  :=  monitor .selectChannel (filter )
141- 			if  err  !=  nil  {
139+ 			if  err  :=  monitor .process (ctx , filter , url ); err  !=  nil  {
142140				log .Error (err )
143141				continue 
144142			}
145143
146- 			if  err  :=  monitor .longPolling (ctx , url , ch ); err  !=  nil  {
147- 				log .Error (err )
148- 			}
149144		}
150145	}
151146}
152147
153- func  (monitor  * Monitor ) selectChannel ( filter   string ) ( interface {},  error )  {
148+ func  (monitor  * Monitor ) process ( ctx  context. Context ,  filter ,  url   string ) error  {
154149	switch  filter  {
155150	case  filterApplied :
156- 		return  monitor .applied ,  nil 
151+ 		return  monitor .longPollingApplied ( ctx ,  url ,  monitor . applied ) 
157152	case  filterBranchDelayed :
158- 		return  monitor .branchDelayed ,  nil 
153+ 		return  monitor .longPollingFailed ( ctx ,  url ,  monitor . branchDelayed ) 
159154	case  filterBranchRefused :
160- 		return  monitor .branchRefused ,  nil 
155+ 		return  monitor .longPollingFailed ( ctx ,  url ,  monitor . branchRefused ) 
161156	case  filterRefused :
162- 		return  monitor .refused ,  nil 
157+ 		return  monitor .longPollingFailed ( ctx ,  url ,  monitor . refused ) 
163158	default :
164- 		return  nil ,  errors .Errorf ("unknown filter: %s" , filter )
159+ 		return  errors .Errorf ("unknown filter: %s" , filter )
165160	}
166161}
167162
168- func  (monitor  * Monitor ) longPolling (ctx  context.Context , url  string , ch  interface {} ) error  {
163+ func  (monitor  * Monitor ) longPollingApplied (ctx  context.Context , url  string , ch  chan  [] * Applied ) error  {
169164	link  :=  fmt .Sprintf ("%s/%s" , monitor .url , url )
170165	req , err  :=  http .NewRequest (http .MethodGet , link , nil )
171166	if  err  !=  nil  {
@@ -179,50 +174,82 @@ func (monitor *Monitor) longPolling(ctx context.Context, url string, ch interfac
179174	if  err  !=  nil  {
180175		return  err 
181176	}
182- 	return  monitor .parseLongPollingResponse (ctx , resp , ch )
177+ 	return  monitor .parseLongPollingAppliedResponse (ctx , resp , ch )
183178}
184179
185- func  (monitor  * Monitor ) parseLongPollingResponse (ctx  context.Context , resp  * http.Response , ch  interface {} ) error  {
180+ func  (monitor  * Monitor ) parseLongPollingAppliedResponse (ctx  context.Context , resp  * http.Response , ch  chan  [] * Applied ) error  {
186181	if  resp  ==  nil  {
187182		return  errors .New ("nil response on mempool long polling request" )
188183	}
189184	if  ch  ==  nil  {
190185		return  errors .New ("nil output channel during mempool long polling request" )
191186	}
192187
193- 	typ  :=  reflect .TypeOf (ch )
194- 	if  typ .Kind () !=  reflect .Chan  {
195- 		return  errors .Errorf ("invalid channel type: %T" , ch )
188+ 	decoder  :=  json .NewDecoder (resp .Body )
189+ 
190+ 	for  {
191+ 		select  {
192+ 		case  <- ctx .Done ():
193+ 			return  ctx .Err ()
194+ 		default :
195+ 			for  decoder .More () {
196+ 				value  :=  make ([]* Applied , 0 )
197+ 				if  err  :=  decoder .Decode (& value ); err  !=  nil  {
198+ 					if  err  ==  io .EOF  ||  err  ==  io .ErrUnexpectedEOF  {
199+ 						return  nil 
200+ 					}
201+ 					return  err 
202+ 				}
203+ 				ch  <-  value 
204+ 			}
205+ 			time .Sleep (time .Millisecond ) // sleeping for CPU usage decreasing 
206+ 		}
196207	}
208+ }
197209
198- 	decoder  :=  json .NewDecoder (resp .Body )
199- 	cases  :=  []reflect.SelectCase {
200- 		{
201- 			Dir :  reflect .SelectSend ,
202- 			Chan : reflect .ValueOf (ch ),
203- 		},
204- 		{
205- 			Dir :  reflect .SelectRecv ,
206- 			Chan : reflect .ValueOf (ctx .Done ()),
207- 		},
210+ func  (monitor  * Monitor ) longPollingFailed (ctx  context.Context , url  string , ch  chan  []* FailedMonitor ) error  {
211+ 	link  :=  fmt .Sprintf ("%s/%s" , monitor .url , url )
212+ 	req , err  :=  http .NewRequest (http .MethodGet , link , nil )
213+ 	if  err  !=  nil  {
214+ 		return  err 
208215	}
216+ 	client  :=  http.Client {
217+ 		Timeout : time .Minute ,
218+ 	}
219+ 
220+ 	resp , err  :=  client .Do (req )
221+ 	if  err  !=  nil  {
222+ 		return  err 
223+ 	}
224+ 	return  monitor .parseLongPollingFailedResponse (ctx , resp , ch )
225+ }
226+ 
227+ func  (monitor  * Monitor ) parseLongPollingFailedResponse (ctx  context.Context , resp  * http.Response , ch  chan  []* FailedMonitor ) error  {
228+ 	if  resp  ==  nil  {
229+ 		return  errors .New ("nil response on mempool long polling request" )
230+ 	}
231+ 	if  ch  ==  nil  {
232+ 		return  errors .New ("nil output channel during mempool long polling request" )
233+ 	}
234+ 
235+ 	decoder  :=  json .NewDecoder (resp .Body )
209236
210237	for  {
211238		select  {
212239		case  <- ctx .Done ():
213240			return  ctx .Err ()
214241		default :
215- 			value  :=  reflect .New (typ .Elem ())
216- 			if  err  :=  decoder .Decode (value .Interface ()); err  !=  nil  {
217- 				if  err  ==  io .EOF  ||  err  ==  io .ErrUnexpectedEOF  {
218- 					return  nil 
242+ 			for  decoder .More () {
243+ 				value  :=  make ([]* FailedMonitor , 0 )
244+ 				if  err  :=  decoder .Decode (& value ); err  !=  nil  {
245+ 					if  err  ==  io .EOF  ||  err  ==  io .ErrUnexpectedEOF  {
246+ 						return  nil 
247+ 					}
248+ 					return  err 
219249				}
220- 				return  err 
221- 			}
222- 			cases [0 ].Send  =  value .Elem ()
223- 			if  chosen , _ , _  :=  reflect .Select (cases ); chosen  ==  1  {
224- 				return  ctx .Err ()
250+ 				ch  <-  value 
225251			}
252+ 			time .Sleep (time .Millisecond ) // sleeping for CPU usage decreasing 
226253		}
227254	}
228255}
0 commit comments