@@ -97,14 +97,14 @@ func (e *Endure) implProvidesPath(vertexID string, vertex interface{}) error {
9797 return nil
9898}
9999
100- func (e * Endure ) addCollectorsDeps (vertexID string , vertex interface {} ) error {
100+ func (e * Endure ) addCollectorsDeps (vertex * Vertex ) error {
101101 // hot path
102- if _ , ok := vertex .(Collector ); ! ok {
102+ if _ , ok := vertex .Iface . (Collector ); ! ok {
103103 return nil
104104 }
105105
106106 // vertex implements Collector interface
107- return e .implCollectorPath (vertexID , vertex )
107+ return e .implCollectorPath (vertex )
108108}
109109
110110func (e * Endure ) walk (params []reflect.Type , v * Vertex ) bool {
@@ -127,9 +127,10 @@ func (e *Endure) walk(params []reflect.Type, v *Vertex) bool {
127127 return true
128128}
129129
130- func (e * Endure ) implCollectorPath (vertexID string , vertex interface {}) error {
130+ func (e * Endure ) implCollectorPath (vertex * Vertex ) error {
131+ // vertexID string, vertex interface{} same vertex
131132 const op = errors .Op ("add_collectors_deps" )
132- collector := vertex .(Collector )
133+ collector := vertex .Iface . (Collector )
133134 // range Collectors functions
134135 for _ , fn := range collector .Collects () {
135136 haveInterfaceDeps := false
@@ -145,149 +146,170 @@ func (e *Endure) implCollectorPath(vertexID string, vertex interface{}) error {
145146 // filter out interfaces, leave only structs
146147 for i := 0 ; i < len (e .graph .Vertices ); i ++ {
147148 // skip self
148- if e .graph .Vertices [i ].ID == vertexID {
149+ if e .graph .Vertices [i ].ID == vertex . ID {
149150 continue
150151 }
151152 if e .walk (params , e .graph .Vertices [i ]) == true {
152153 compatible = append (compatible , e .graph .Vertices [i ])
153154 // set, that we have interface deps
154155 haveInterfaceDeps = true
156+ e .logger .Info ("vertex is compatible with Collects" , zap .String ("vertex id" , e .graph .Vertices [i ].ID ), zap .String ("collects from vertex" , vertex .ID ))
157+ continue
155158 }
159+ e .logger .Info ("vertex is not compatible with Collects" , zap .String ("vertex id" , e .graph .Vertices [i ].ID ), zap .String ("collects from vertex" , vertex .ID ))
160+ }
161+
162+ if len (compatible ) == 0 && haveInterfaceDeps {
163+ e .logger .Info ("no compatible vertices found" , zap .String ("collects from vertex" , vertex .ID ))
164+ return nil
156165 }
157- // traverse
166+ // process mixed deps (interfaces + structs)
158167 if haveInterfaceDeps {
159- for _ , compat := range compatible {
160- // add vertex itself
161- cp := CollectorEntry {
162- in : make ([]In , 0 , 0 ),
163- fn : getFunctionName (fn ),
164- }
165- cp .in = append (cp .in , In {
166- in : reflect .ValueOf (vertex ),
167- dep : vertexID ,
168- })
168+ return e .processInterfaceDeps (compatible , fn , vertex , params )
169+ }
170+ // process only struct deps if not interfaces were found
171+ return e .processStructDeps (fn , vertex , params )
172+ }
173+ return nil
174+ }
169175
170- for _ , param := range params {
171- // check if type is primitive type
172- if isPrimitive (param .String ()) {
173- e .logger .Panic ("primitive type in the function parameters" , zap .String ("vertex id" , vertexID ), zap .String ("type" , param .String ()))
174- }
176+ func (e * Endure ) processInterfaceDeps (compatible Vertices , fn interface {}, vertex * Vertex , params []reflect.Type ) error {
177+ const op = errors .Op ("process interface deps" )
178+ for _ , compat := range compatible {
179+ // add vertex itself
180+ cp := CollectorEntry {
181+ in : make ([]In , 0 , 0 ),
182+ fn : getFunctionName (fn ),
183+ }
184+ cp .in = append (cp .in , In {
185+ in : reflect .ValueOf (vertex .Iface ),
186+ dep : vertex .ID ,
187+ })
188+
189+ for _ , param := range params {
190+ // check if type is primitive type
191+ if isPrimitive (param .String ()) {
192+ e .logger .Panic ("primitive type in the function parameters" , zap .String ("vertex id" , vertex .ID ), zap .String ("type" , param .String ()))
193+ }
175194
176- paramStr := param .String ()
177- if vertexID == paramStr {
178- continue
179- }
195+ paramStr := param .String ()
196+ if vertex . ID == paramStr {
197+ continue
198+ }
180199
181- switch param .Kind () {
182- case reflect .Ptr :
183- if param .Elem ().Kind () == reflect .Struct {
184- dep := e .graph .VerticesMap [(removePointerAsterisk (param .String ()))]
185- if dep == nil {
186- panic ("can't find provider" )
187- }
188-
189- cp .in = append (cp .in , In {
190- in : reflect .ValueOf (dep .Iface ),
191- dep : dep .ID ,
192- })
193-
194- err = e .graph .AddDep (vertexID , removePointerAsterisk (dep .ID ), Collects , isReference (param ), param .Kind ())
195- if err != nil {
196- return errors .E (op , err )
197- }
198- }
199- case reflect .Interface :
200- cp .in = append (cp .in , In {
201- in : reflect .ValueOf (compat .Iface ),
202- dep : compat .ID ,
203- })
204-
205- err = e .graph .AddDep (vertexID , removePointerAsterisk (compat .ID ), Collects , isReference (param ), param .Kind ())
206- if err != nil {
207- return errors .E (op , err )
208- }
209-
210- case reflect .Struct :
211- dep := e .graph .VerticesMap [(removePointerAsterisk (param .String ()))]
212- if dep == nil {
213- panic ("can't find provider" )
214- }
215-
216- cp .in = append (cp .in , In {
217- in : reflect .ValueOf (dep .Iface ),
218- dep : dep .ID ,
219- })
220-
221- err = e .graph .AddDep (vertexID , removePointerAsterisk (dep .ID ), Collects , isReference (param ), param .Kind ())
222- if err != nil {
223- return errors .E (op , err )
224- }
200+ switch param .Kind () {
201+ case reflect .Ptr :
202+ if param .Elem ().Kind () == reflect .Struct {
203+ dep := e .graph .VerticesMap [(removePointerAsterisk (param .String ()))]
204+ if dep == nil {
205+ return errors .E (op , errors .Errorf ("can't find provider for the struct parameter: %s" , removePointerAsterisk (param .String ())))
225206 }
226- }
227- v := e .graph .GetVertex (vertexID )
228- v .Meta .FnsCollectorToInvoke = append (v .Meta .FnsCollectorToInvoke , cp )
229- }
230- } else {
231- cp := CollectorEntry {
232- in : make ([]In , 0 , 0 ),
233- fn : getFunctionName (fn ),
234- }
235- cp .in = append (cp .in , In {
236- in : reflect .ValueOf (vertex ),
237- dep : vertexID ,
238- })
239207
240- for _ , param := range params {
241- // check if type is primitive type
242- if isPrimitive (param .String ()) {
243- e .logger .Panic ("primitive type in the function parameters" , zap .String ("vertex id" , vertexID ), zap .String ("type" , param .String ()))
208+ cp .in = append (cp .in , In {
209+ in : reflect .ValueOf (dep .Iface ),
210+ dep : dep .ID ,
211+ })
212+
213+ err := e .graph .AddDep (vertex .ID , removePointerAsterisk (dep .ID ), Collects , isReference (param ), param .Kind ())
214+ if err != nil {
215+ return errors .E (op , err )
216+ }
244217 }
218+ case reflect .Interface :
219+ cp .in = append (cp .in , In {
220+ in : reflect .ValueOf (compat .Iface ),
221+ dep : compat .ID ,
222+ })
245223
246- // skip self
247- paramStr := param .String ()
248- if vertexID == paramStr {
249- continue
224+ err := e .graph .AddDep (vertex .ID , removePointerAsterisk (compat .ID ), Collects , isReference (param ), param .Kind ())
225+ if err != nil {
226+ return errors .E (op , err )
250227 }
251228
229+ case reflect .Struct :
252230 dep := e .graph .VerticesMap [(removePointerAsterisk (param .String ()))]
253231 if dep == nil {
254- depIds := e .graph .FindProviders (removePointerAsterisk (paramStr ))
255- if len (depIds ) == 0 {
256- panic ("can't find provider for dep" )
257- }
258- dep = depIds [0 ]
259- for k , v := range dep .Provides {
260- if k == removePointerAsterisk (paramStr ) {
261- cp .in = append (cp .in , In {
262- in : reflect .Zero (reflect .TypeOf (v )),
263- dep : k ,
264- })
265- }
266- }
267- } else {
268- cp .in = append (cp .in , In {
269- in : reflect .ValueOf (dep .Iface ),
270- dep : dep .ID ,
271- })
232+ return errors .E (op , errors .Errorf ("can't find provider for the struct parameter: %s" , removePointerAsterisk (param .String ())))
272233 }
273234
274- tmpIsRef := isReference ( param )
275- tmpValue := reflect .ValueOf (dep .Iface )
276- e . graph . AddGlobalProvider ( removePointerAsterisk ( paramStr ), tmpValue )
277- e . graph . VerticesMap [ dep . ID ]. AddProvider ( removePointerAsterisk ( paramStr ), tmpValue , tmpIsRef , param . Kind () )
235+ cp . in = append ( cp . in , In {
236+ in : reflect .ValueOf (dep .Iface ),
237+ dep : dep . ID ,
238+ } )
278239
279- err = e .graph .AddDep (vertexID , removePointerAsterisk (paramStr ), Collects , isReference (param ), param .Kind ())
240+ err : = e .graph .AddDep (vertex . ID , removePointerAsterisk (dep . ID ), Collects , isReference (param ), param .Kind ())
280241 if err != nil {
281242 return errors .E (op , err )
282243 }
244+ }
245+ }
246+ vertex .Meta .CollectorEntries = append (vertex .Meta .CollectorEntries , cp )
247+ }
248+
249+ return nil
250+ }
251+
252+ func (e * Endure ) processStructDeps (fn interface {}, vertex * Vertex , params []reflect.Type ) error {
253+ const op = errors .Op ("process struct deps" )
254+ // process only struct deps
255+ cp := CollectorEntry {
256+ in : make ([]In , 0 , 0 ),
257+ fn : getFunctionName (fn ),
258+ }
259+ cp .in = append (cp .in , In {
260+ in : reflect .ValueOf (vertex .Iface ),
261+ dep : vertex .ID ,
262+ })
263+
264+ for _ , param := range params {
265+ // check if type is primitive type
266+ if isPrimitive (param .String ()) {
267+ e .logger .Panic ("primitive type in the function parameters" , zap .String ("vertex id" , vertex .ID ), zap .String ("type" , param .String ()))
268+ }
283269
284- e .logger .Debug ("adding dependency via Collects()" , zap .String ("vertex id" , vertexID ), zap .String ("depends" , paramStr ))
270+ // skip self
271+ paramStr := param .String ()
272+ if vertex .ID == paramStr {
273+ continue
274+ }
275+
276+ dep := e .graph .VerticesMap [(removePointerAsterisk (param .String ()))]
277+ if dep == nil {
278+ depIds := e .graph .FindProviders (removePointerAsterisk (paramStr ))
279+ if len (depIds ) == 0 {
280+ e .logger .Warn ("can't find any provider for the dependency, collector function on the vertex will not be invoked" , zap .String ("dep id" , removePointerAsterisk (param .String ())), zap .String ("vertexId" , vertex .ID ))
281+ return nil
285282 }
283+ dep = depIds [0 ]
284+ for k , v := range dep .Provides {
285+ if k == removePointerAsterisk (paramStr ) {
286+ cp .in = append (cp .in , In {
287+ in : reflect .Zero (reflect .TypeOf (v )),
288+ dep : k ,
289+ })
290+ }
291+ }
292+ } else {
293+ cp .in = append (cp .in , In {
294+ in : reflect .ValueOf (dep .Iface ),
295+ dep : dep .ID ,
296+ })
297+ }
298+
299+ tmpIsRef := isReference (param )
300+ tmpValue := reflect .ValueOf (dep .Iface )
301+ e .graph .AddGlobalProvider (removePointerAsterisk (paramStr ), tmpValue )
302+ e .graph .VerticesMap [dep .ID ].AddProvider (removePointerAsterisk (paramStr ), tmpValue , tmpIsRef , param .Kind ())
286303
287- v := e .graph .GetVertex (vertexID )
288- v .Meta .FnsCollectorToInvoke = append (v .Meta .FnsCollectorToInvoke , cp )
304+ err := e .graph .AddDep (vertex .ID , removePointerAsterisk (paramStr ), Collects , isReference (param ), param .Kind ())
305+ if err != nil {
306+ return errors .E (op , err )
289307 }
308+
309+ e .logger .Debug ("adding dependency via Collects()" , zap .String ("vertex id" , vertex .ID ), zap .String ("depends" , paramStr ))
290310 }
311+
312+ vertex .Meta .CollectorEntries = append (vertex .Meta .CollectorEntries , cp )
291313 return nil
292314}
293315
@@ -314,7 +336,7 @@ func (e *Endure) addEdges() error {
314336 5. FunctionName of the dependencies which we should found
315337 We add 3 and 4 points to the Vertex
316338 */
317- err := e .addCollectorsDeps (vertexID , vrtx . Iface )
339+ err := e .addCollectorsDeps (vrtx )
318340 if err != nil {
319341 return errors .E (Op , err )
320342 }
0 commit comments