Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new: WithAlternateMethodName #206

Merged
merged 2 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
uses: golangci/golangci-lint-action@v3
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.57
version: v1.61

test:
name: Test and Coverage
Expand Down
32 changes: 31 additions & 1 deletion client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ func (s *simpleHub) Callback(arg1 string) {
s.Hub.Clients().Caller().Send("OnCallback", strings.ToUpper(arg1))
}

func (s *simpleHub) SwearBack(arg1 string) {
s.Hub.Clients().Caller().Send("#@!", strings.ToUpper(arg1))
}

func (s *simpleHub) ReadStream(i int) chan string {
ch := make(chan string)
go func() {
Expand Down Expand Up @@ -279,6 +283,31 @@ var _ = Describe("Client", func() {
cancelClient()
close(done)
}, 5.0)
It("should invoke a server method and get the result via callback with alternate name", func(done Done) {
receiver := &simpleReceiver{}
_, client, _, cancelClient := getTestBed(receiver, formatOption)
receiver.result.Store("x")
errCh := client.Send("SwearBack", "low")
ch := make(chan string, 1)
go func() {
for {
if result, ok := receiver.result.Load().(string); ok {
if result != "x" {
ch <- result
break
}
}
}
}()
select {
case val := <-ch:
Expect(val).To(Equal("LOW"))
case err := <-errCh:
Expect(err).NotTo(HaveOccurred())
}
cancelClient()
close(done)
}, 5.0)
It("should invoke a server method and return the error when arguments don't match", func(done Done) {
receiver := &simpleReceiver{}
_, client, _, cancelClient := getTestBed(receiver, formatOption)
Expand Down Expand Up @@ -480,7 +509,8 @@ func getTestBed(receiver interface{}, formatOption func(Party) error) (Server, C
// Create the Client
var ctx context.Context
ctx, cancelClient := context.WithCancel(context.Background())
client, _ := NewClient(ctx, WithConnection(cliConn), WithReceiver(receiver), testLoggerOption(), formatOption)
client, _ := NewClient(ctx, WithConnection(cliConn), WithReceiver(receiver),
WithAlternateMethodName("OnCallback", "#@!"), testLoggerOption(), formatOption)
// Start it
client.Start()
return server, client, cliConn, cancelClient
Expand Down
12 changes: 12 additions & 0 deletions invocation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ var _ = Describe("Invocation", func() {
close(done)
}, 2.0)
})
Context("When invoked by the client with alternate method name", func() {
It("should be invoked and return a completion", func(done Done) {
conn.ClientSend(`{"type":1,"invocationId": "123","target":"."}`)
Expect(<-invocationQueue).To(Equal("Simple()"))
recv := (<-conn.received).(completionMessage)
Expect(recv).NotTo(BeNil())
Expect(recv.InvocationID).To(Equal("123"))
Expect(recv.Result).To(BeNil())
Expect(recv.Error).To(Equal(""))
close(done)
}, 2.0)
})
Context("When invoked by the client two times in one frame", func() {
It("should be invoked and return a completion", func(done Done) {
conn.ClientSend(`{"type":1,"invocationId": "123","target":"simple"}`)
Expand Down
3 changes: 2 additions & 1 deletion loop.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,8 @@ func (l *loop) GetNewID() string {
func (l *loop) handleInvocationMessage(invocation invocationMessage) {
_ = l.dbg.Log(evt, msgRecv, msg, fmtMsg(invocation))
// Transient hub, dispatch invocation here
if method, ok := getMethod(l.party.invocationTarget(l.hubConn), invocation.Target); !ok {
methodName := l.party.getMethodNameByAlternateName(invocation.Target)
if method, ok := getMethod(l.party.invocationTarget(l.hubConn), methodName); !ok {
// Unable to find the method
_ = l.info.Log(evt, "getMethod", "error", "missing method", "name", invocation.Target, react, "send completion with error")
_ = l.hubConn.Completion(invocation.InvocationID, nil, fmt.Sprintf("Unknown method %s", invocation.Target))
Expand Down
10 changes: 10 additions & 0 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,13 @@ func buildInfoDebugLogger(logger log.Logger, debug bool) (log.Logger, log.Logger
debugLogger := log.With(&recoverLogger{level.Debug(logger)}, "caller", log.DefaultCaller)
return infoLogger, debugLogger
}

// WithAlternateMethodName sets an alternate method name for hub or receiver method. This might be necessary
// if the invocation target used by existing clients for invocations or by existing servers for callback invocations
// is not a name that can be used as a Go method name.
func WithAlternateMethodName(methodName, alternateName string) func(Party) error {
return func(p Party) error {
p.setAlternateMethodName(methodName, alternateName)
return nil
}
}
17 changes: 17 additions & 0 deletions party.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ type Party interface {
enableDetailedErrors() bool
setEnableDetailedErrors(enable bool)

setAlternateMethodName(methodName, alternateName string)
getMethodNameByAlternateName(alternateName string) (methodName string)

loggers() (info StructuredLogger, dbg StructuredLogger)
setLoggers(info StructuredLogger, dbg StructuredLogger)

Expand All @@ -69,6 +72,7 @@ func newPartyBase(parentContext context.Context, info log.Logger, dbg log.Logger
_enableDetailedErrors: false,
_insecureSkipVerify: false,
_originPatterns: nil,
methodNamesByAlternateName: make(map[string]string),
info: info,
dbg: dbg,
}
Expand All @@ -86,6 +90,7 @@ type partyBase struct {
_enableDetailedErrors bool
_insecureSkipVerify bool
_originPatterns []string
methodNamesByAlternateName map[string]string
info StructuredLogger
dbg StructuredLogger
wg sync.WaitGroup
Expand Down Expand Up @@ -181,3 +186,15 @@ func (p *partyBase) loggers() (info StructuredLogger, debug StructuredLogger) {
func (p *partyBase) waitGroup() *sync.WaitGroup {
return &p.wg
}

func (p *partyBase) setAlternateMethodName(methodName, alternateName string) {
p.methodNamesByAlternateName[alternateName] = methodName
}

func (p *partyBase) getMethodNameByAlternateName(alternateName string) (methodName string) {
var ok bool
if methodName, ok = p.methodNamesByAlternateName[alternateName]; !ok {
methodName = alternateName
}
return methodName
}
4 changes: 3 additions & 1 deletion signalr_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ func connect(hubProto HubInterface) (Server, *testingConnection) {
server, err := NewServer(context.TODO(), SimpleHubFactory(hubProto),
testLoggerOption(),
ChanReceiveTimeout(200*time.Millisecond),
StreamBufferCapacity(5))
StreamBufferCapacity(5),
WithAlternateMethodName("Simple", "."),
)
if err != nil {
Fail(err.Error())
return nil, nil
Expand Down
Loading