Skip to content

Commit 3c4e186

Browse files
committed
[core] Ensure doNewEnvironmentAsync gets its own copy of args
1 parent 02e5d7f commit 3c4e186

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

core/server.go

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ package core
2828

2929
import (
3030
"encoding/json"
31+
"maps"
3132
"runtime"
3233
"sort"
3334
"strconv"
@@ -294,26 +295,23 @@ func (m *RpcServer) GetEnvironments(cxt context.Context, request *pb.GetEnvironm
294295
return r, nil
295296
}
296297

297-
func (m *RpcServer) doNewEnvironmentAsync(cxt context.Context, request *pb.NewEnvironmentRequest, id uid.ID) {
298+
func (m *RpcServer) doNewEnvironmentAsync(cxt context.Context, userVars map[string]string, requestUser *evpb.User, workflowTemplate string, public bool, autoTransition bool, id uid.ID) {
298299
var err error
299-
userVars := request.GetVars()
300-
if len(userVars) == 0 {
301-
userVars = make(map[string]string)
302-
}
300+
303301
// we store the last known request user in the environment
304-
lastRequestUserJ, _ := json.Marshal(request.RequestUser)
302+
lastRequestUserJ, _ := json.Marshal(requestUser)
305303
userVars["last_request_user"] = string(lastRequestUserJ[:])
306-
id, err = m.state.environments.CreateEnvironment(request.GetWorkflowTemplate(), userVars, request.GetPublic(), id, request.GetAutoTransition())
304+
id, err = m.state.environments.CreateEnvironment(workflowTemplate, userVars, public, id, autoTransition)
307305
if err != nil {
308306
the.EventWriterWithTopic(topic.Environment).WriteEvent(&evpb.Ev_EnvironmentEvent{
309307
EnvironmentId: id.String(),
310308
State: "ERROR",
311309
Error: "cannot create new environment",
312310
Message: err.Error(),
313-
LastRequestUser: request.RequestUser,
311+
LastRequestUser: requestUser,
314312
WorkflowTemplateInfo: &evpb.WorkflowTemplateInfo{
315-
Public: request.GetPublic(),
316-
Path: request.GetWorkflowTemplate(),
313+
Public: public,
314+
Path: workflowTemplate,
317315
},
318316
})
319317
return
@@ -326,10 +324,10 @@ func (m *RpcServer) doNewEnvironmentAsync(cxt context.Context, request *pb.NewEn
326324
State: "ERROR",
327325
Error: "cannot get newly created environment",
328326
Message: err.Error(),
329-
LastRequestUser: request.RequestUser,
327+
LastRequestUser: requestUser,
330328
WorkflowTemplateInfo: &evpb.WorkflowTemplateInfo{
331-
Public: request.GetPublic(),
332-
Path: request.GetWorkflowTemplate(),
329+
Public: public,
330+
Path: workflowTemplate,
333331
},
334332
})
335333
return
@@ -338,7 +336,7 @@ func (m *RpcServer) doNewEnvironmentAsync(cxt context.Context, request *pb.NewEn
338336
the.EventWriterWithTopic(topic.Environment).WriteEvent(&evpb.Ev_EnvironmentEvent{
339337
EnvironmentId: id.String(),
340338
State: newEnv.CurrentState(),
341-
LastRequestUser: request.RequestUser,
339+
LastRequestUser: requestUser,
342340
WorkflowTemplateInfo: newEnv.GetWorkflowInfo(),
343341
})
344342
return
@@ -351,7 +349,11 @@ func (m *RpcServer) NewEnvironmentAsync(cxt context.Context, request *pb.NewEnvi
351349
// Create new Environment instance with some roles, we get back a UUID
352350
id := uid.New()
353351

354-
go m.doNewEnvironmentAsync(cxt, request, id)
352+
// We must make a copy of the userVars, otherwise there will be a race for access with gRPC
353+
userVars := make(map[string]string)
354+
if len(request.GetVars()) > 0 {
355+
maps.Copy(userVars, request.GetVars())
356+
}
355357

356358
ei := &pb.EnvironmentInfo{
357359
Id: id.String(),
@@ -362,6 +364,9 @@ func (m *RpcServer) NewEnvironmentAsync(cxt context.Context, request *pb.NewEnvi
362364
Environment: ei,
363365
Public: request.GetPublic(),
364366
}
367+
368+
go m.doNewEnvironmentAsync(cxt, userVars, request.GetRequestUser(), request.GetWorkflowTemplate(), request.GetPublic(), request.GetAutoTransition(), id)
369+
365370
return
366371
}
367372

0 commit comments

Comments
 (0)