1- // Copyright (c) 2021-2023 Cisco and/or its affiliates.
1+ // Copyright (c) 2021-2024 Cisco and/or its affiliates.
22//
33// SPDX-License-Identifier: Apache-2.0
44//
@@ -29,6 +29,12 @@ import (
2929 "github.com/networkservicemesh/sdk/pkg/networkservice/core/next"
3030)
3131
32+ type errorEventFactoryInconsistency struct {}
33+
34+ func (e * errorEventFactoryInconsistency ) Error () string {
35+ return "errorEventFactoryInconsistency error"
36+ }
37+
3238type connectionState int
3339
3440const (
@@ -52,19 +58,26 @@ type eventFactoryClient struct {
5258 ctxFunc func () (context.Context , context.CancelFunc )
5359 request * networkservice.NetworkServiceRequest
5460 returnedConnection * networkservice.Connection
55- opts []grpc.CallOption
61+ grpcOpts []grpc.CallOption
5662 client networkservice.NetworkServiceClient
63+ beforeRequestFunc func () error
5764 afterCloseFunc func ()
5865}
5966
60- func newEventFactoryClient (ctx context.Context , afterClose func (), opts ... grpc. CallOption ) * eventFactoryClient {
67+ func newEventFactoryClient (ctx context.Context , actualEventFactoryFunc func () * eventFactoryClient , afterClose func () ) * eventFactoryClient {
6168 f := & eventFactoryClient {
6269 client : next .Client (ctx ),
6370 initialCtxFunc : postpone .Context (ctx ),
64- opts : opts ,
6571 }
6672 f .updateContext (ctx )
6773
74+ f .beforeRequestFunc = func () error {
75+ if actualEventFactoryFunc != nil && actualEventFactoryFunc () != f {
76+ return & errorEventFactoryInconsistency {}
77+ }
78+ return nil
79+ }
80+
6881 f .afterCloseFunc = func () {
6982 f .state = closed
7083 if afterClose != nil {
@@ -90,18 +103,29 @@ func (f *eventFactoryClient) Request(opts ...Option) <-chan error {
90103 opt (o )
91104 }
92105 ch := make (chan error , 1 )
106+
93107 f .executor .AsyncExec (func () {
94108 defer close (ch )
95- if f .state != established {
109+ if err := f .beforeRequestFunc (); err != nil {
110+ ch <- err
96111 return
97112 }
98113 select {
99114 case <- o .cancelCtx .Done ():
100115 default :
101116 request := f .request .Clone ()
117+ grpcOpts := f .grpcOpts
118+ if o .userRequest != nil {
119+ request = o .userRequest
120+ request .Connection = mergeConnection (f .returnedConnection , o .userRequest .Connection , f .request .GetConnection ())
121+ }
122+ if o .grpcOpts != nil {
123+ grpcOpts = o .grpcOpts
124+ }
125+
102126 if o .reselect {
103127 ctx , cancel := f .ctxFunc ()
104- _ , _ = f .client .Close (ctx , request .GetConnection (), f . opts ... )
128+ _ , _ = f .client .Close (ctx , request .GetConnection (), grpcOpts ... )
105129 if request .GetConnection () != nil {
106130 request .GetConnection ().Mechanism = nil
107131 request .GetConnection ().NetworkServiceEndpointName = ""
@@ -110,12 +134,32 @@ func (f *eventFactoryClient) Request(opts ...Option) <-chan error {
110134 }
111135 cancel ()
112136 }
113- ctx , cancel := f .ctxFunc ()
114- defer cancel ()
115- conn , err := f .client .Request (ctx , request , f .opts ... )
116- if err == nil && f .request != nil {
117- f .request .Connection = conn
137+
138+ var ctx context.Context
139+ if o .ctx != nil {
140+ ctx = withEventFactory (o .ctx , f )
141+ } else {
142+ var cancel context.CancelFunc
143+ ctx , cancel = f .ctxFunc ()
144+ defer cancel ()
145+ }
146+
147+ conn , err := f .client .Request (ctx , request , grpcOpts ... )
148+ if err == nil {
149+ f .request = request .Clone ()
150+ f .request .Connection = conn .Clone ()
151+ f .grpcOpts = grpcOpts
152+ f .state = established
118153 f .request .Connection .State = networkservice .State_UP
154+ if o .connectionToReturn != nil {
155+ f .returnedConnection = conn .Clone ()
156+ * o .connectionToReturn = conn .Clone ()
157+ }
158+ f .updateContext (ctx )
159+ } else {
160+ if f .state != established {
161+ f .afterCloseFunc ()
162+ }
119163 }
120164 ch <- err
121165 }
@@ -130,18 +174,26 @@ func (f *eventFactoryClient) Close(opts ...Option) <-chan error {
130174 for _ , opt := range opts {
131175 opt (o )
132176 }
177+
133178 ch := make (chan error , 1 )
134179 f .executor .AsyncExec (func () {
135180 defer close (ch )
136- if f .request == nil {
181+ if f .request == nil || f . state != established {
137182 return
138183 }
184+
139185 select {
140186 case <- o .cancelCtx .Done ():
141187 default :
188+ grpcOpts := f .grpcOpts
189+ if o .grpcOpts != nil {
190+ grpcOpts = o .grpcOpts
191+ }
192+
142193 ctx , cancel := f .ctxFunc ()
143194 defer cancel ()
144- _ , err := f .client .Close (ctx , f .request .GetConnection (), f .opts ... )
195+
196+ _ , err := f .client .Close (ctx , f .request .GetConnection (), grpcOpts ... )
145197 f .afterCloseFunc ()
146198 ch <- err
147199 }
@@ -158,17 +210,25 @@ type eventFactoryServer struct {
158210 ctxFunc func () (context.Context , context.CancelFunc )
159211 request * networkservice.NetworkServiceRequest
160212 returnedConnection * networkservice.Connection
161- afterCloseFunc func ()
162213 server networkservice.NetworkServiceServer
214+ beforeRequestFunc func () error
215+ afterCloseFunc func ()
163216}
164217
165- func newEventFactoryServer (ctx context.Context , afterClose func ()) * eventFactoryServer {
218+ func newEventFactoryServer (ctx context.Context , actualEventFactoryFunc func () * eventFactoryServer , afterClose func ()) * eventFactoryServer {
166219 f := & eventFactoryServer {
167220 server : next .Server (ctx ),
168221 initialCtxFunc : postpone .Context (ctx ),
169222 }
170223 f .updateContext (ctx )
171224
225+ f .beforeRequestFunc = func () error {
226+ if actualEventFactoryFunc != nil && actualEventFactoryFunc () != f {
227+ return & errorEventFactoryInconsistency {}
228+ }
229+ return nil
230+ }
231+
172232 f .afterCloseFunc = func () {
173233 f .state = closed
174234 afterClose ()
@@ -194,17 +254,48 @@ func (f *eventFactoryServer) Request(opts ...Option) <-chan error {
194254 ch := make (chan error , 1 )
195255 f .executor .AsyncExec (func () {
196256 defer close (ch )
197- if f .state != established {
257+ if err := f .beforeRequestFunc (); err != nil {
258+ ch <- err
198259 return
199260 }
200261 select {
201262 case <- o .cancelCtx .Done ():
202263 default :
203- ctx , cancel := f .ctxFunc ()
204- defer cancel ()
205- conn , err := f .server .Request (ctx , f .request )
206- if err == nil && f .request != nil {
207- f .request .Connection = conn
264+ request := f .request .Clone ()
265+ if o .userRequest != nil {
266+ request = o .userRequest
267+ }
268+ if f .state == established && request .GetConnection ().GetState () == networkservice .State_RESELECT_REQUESTED {
269+ ctx , cancel := f .ctxFunc ()
270+ _ , _ = f .server .Close (ctx , f .request .GetConnection ())
271+ f .state = closed
272+ cancel ()
273+ }
274+
275+ var ctx context.Context
276+ if o .ctx != nil {
277+ ctx = withEventFactory (o .ctx , f )
278+ } else {
279+ var cancel context.CancelFunc
280+ ctx , cancel = f .ctxFunc ()
281+ defer cancel ()
282+ }
283+
284+ conn , err := f .server .Request (ctx , request )
285+ if err == nil {
286+ f .request = request .Clone ()
287+ f .request .Connection = conn .Clone ()
288+ f .state = established
289+ f .request .Connection .State = networkservice .State_UP
290+ if o .connectionToReturn != nil {
291+ f .returnedConnection = conn .Clone ()
292+ * o .connectionToReturn = conn .Clone ()
293+ }
294+ f .updateContext (ctx )
295+ } else {
296+ if f .state != established {
297+ f .afterCloseFunc ()
298+ }
208299 }
209300 ch <- err
210301 }
@@ -222,7 +313,7 @@ func (f *eventFactoryServer) Close(opts ...Option) <-chan error {
222313 ch := make (chan error , 1 )
223314 f .executor .AsyncExec (func () {
224315 defer close (ch )
225- if f .request == nil {
316+ if f .request == nil || f . state != established {
226317 return
227318 }
228319 select {
0 commit comments