func (resource *LeverResource) closeInternal(soft bool) { if resource.closing { return } resource.closing = true resource.expiryTimer.Stop() resource.sessionKAB.Close() // TODO: Is it ok to hold lock while doing RPC within container? // What happens if call takes a really long time? // Send RPC inside container to tell that resource closed. if !soft { conn, err := resource.conns.Dial(resource.instanceAddr) if err != nil { resource.logger.WithFields("err", err).Error( "Failed to dial in Lever instance") go resource.onCloseFun(resource.leverResource, err) return } leverURL := &core.LeverURL{ Environment: resource.leverEnv, Service: resource.leverService, Method: "CloseResource", } _, err = core.SendLeverRPC( conn, context.Background(), leverURL, &core.RPC{ ArgsOneof: &core.RPC_Args{ Args: &core.JSONArray{ Element: []*core.JSON{{ JsonValueOneof: &core.JSON_JsonString{ JsonString: resource.leverResource, }, }}, }, }, }) if err != nil { resource.logger.WithFields("err", err).Error( "Failed resource close call") go resource.onCloseFun(resource.leverResource, err) return } } // Async so as not to hog the lock. go func() { err := resource.levResResource.Deregister() if err != nil { resource.logger.WithFields("err", err).Debug( "Resource lock deregister error") } }() go resource.onCloseFun(resource.leverResource, nil) }
func (resource *LeverResource) construct() error { // TODO: Is it ok to hold lock while doing RPC within container? // What happens if call takes a really long time? // Send RPC to instance to inform that it will be hosting this resource. resource.lock.Lock() defer resource.lock.Unlock() conn, err := resource.conns.Dial(resource.instanceAddr) if err != nil { resource.logger.WithFields("err", err).Error( "Failed to dial in Lever instance") return err } leverURL := &core.LeverURL{ Environment: resource.leverEnv, Service: resource.leverService, Method: "NewResource", } _, err = core.SendLeverRPC( conn, context.Background(), leverURL, &core.RPC{ ArgsOneof: &core.RPC_Args{ Args: &core.JSONArray{ Element: []*core.JSON{{ JsonValueOneof: &core.JSON_JsonString{ JsonString: resource.leverResource, }, }}, }, }, }) if err != nil { resource.logger.WithFields("err", err).Error( "Failed resource construct call") return err } return nil }
func (client *Client) invokeInternal( replyObj interface{}, leverURL *core.LeverURL, args ...interface{}) (err error) { if IsChanMethod(leverURL.Method) { return fmt.Errorf( "Use InvokeChan / InvokeChanURL for streaming methods") } if leverURL.Environment == "" && OwnEnvironment == "" { return fmt.Errorf( "Environment not specified and cannot be deduced") } if leverURL.Environment == "" { leverURL.Environment = OwnEnvironment } var dialTo string if client.ForceHost != "" { dialTo = client.ForceHost } else { if (core.IsInternalEnvironment(leverURL.Environment) || leverURL.Environment == OwnEnvironment) && internalRPCGateway != "" { dialTo = internalRPCGateway } else { dialTo = leverURL.Environment } } conn, err := client.conns.Dial(dialTo) if err != nil { return err } rpc := &core.RPC{} if len(args) == 1 { byteArgs, ok := args[0].([]byte) if ok { // Byte args case. rpc.ArgsOneof = &core.RPC_ByteArgs{ ByteArgs: byteArgs, } } } if rpc.ArgsOneof == nil { // Non-byte args case. var encdArgs *core.JSONArray encdArgs, err = encodeArgs(args) if err != nil { return err } rpc.ArgsOneof = &core.RPC_Args{ Args: encdArgs, } } reply, err := core.SendLeverRPC( conn, context.Background(), leverURL, rpc) if err != nil { return err } if reply.GetResultOneof() == nil { return fmt.Errorf("Received nil result oneof") } switch result := reply.GetResultOneof().(type) { case *core.RPCReply_ByteResult: byteReplyObj, ok := replyObj.(*[]byte) if !ok { return fmt.Errorf( "replyObj needs to be type *[]byte when RPC returns bytes") } *byteReplyObj = result.ByteResult return nil case *core.RPCReply_ByteError: return &RemoteByteError{Err: result.ByteError} case *core.RPCReply_Result: return decodeArgAsValue(result.Result, replyObj) case *core.RPCReply_Error: return &RemoteError{Err: buildDataForJSON(result.Error)} default: return fmt.Errorf("Invalid type") } }