Skip to content

Commit

Permalink
Merge pull request #206 from philippseith/feature/alternative_method_…
Browse files Browse the repository at this point in the history
…names

new: WithAlternateMethodName
  • Loading branch information
philippseith authored Nov 6, 2024
2 parents d47b125 + 0d71e1c commit 5c53213
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 4 deletions.
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

0 comments on commit 5c53213

Please sign in to comment.