aboutsummaryrefslogtreecommitdiffstats
path: root/rpc
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2016-04-16 00:05:24 +0800
committerFelix Lange <fjl@twurst.com>2016-04-16 00:10:52 +0800
commita40e61b4ac44a4f64f057a4220a26cfe4b9dcf03 (patch)
tree401218a5f3ed5b4fac88baf87551bd3f57f3c34b /rpc
parent6197fbf8d70c1aa96c3e87de91ff3f46f454c1ea (diff)
downloadgo-tangerine-a40e61b4ac44a4f64f057a4220a26cfe4b9dcf03.tar
go-tangerine-a40e61b4ac44a4f64f057a4220a26cfe4b9dcf03.tar.gz
go-tangerine-a40e61b4ac44a4f64f057a4220a26cfe4b9dcf03.tar.bz2
go-tangerine-a40e61b4ac44a4f64f057a4220a26cfe4b9dcf03.tar.lz
go-tangerine-a40e61b4ac44a4f64f057a4220a26cfe4b9dcf03.tar.xz
go-tangerine-a40e61b4ac44a4f64f057a4220a26cfe4b9dcf03.tar.zst
go-tangerine-a40e61b4ac44a4f64f057a4220a26cfe4b9dcf03.zip
rpc: remove NotifierContextKey
Context keys must have a unique type in order to prevent any unintented clashes. The code used int(1) as key. Fix it by implementing the pattern recommended by package context.
Diffstat (limited to 'rpc')
-rw-r--r--rpc/notification.go9
-rw-r--r--rpc/notification_test.go2
-rw-r--r--rpc/server.go11
3 files changed, 14 insertions, 8 deletions
diff --git a/rpc/notification.go b/rpc/notification.go
index 146d785c9..e84e26a58 100644
--- a/rpc/notification.go
+++ b/rpc/notification.go
@@ -23,6 +23,7 @@ import (
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
+ "golang.org/x/net/context"
)
var (
@@ -62,6 +63,14 @@ type Notifier interface {
Unsubscribe(id string) error
}
+type notifierKey struct{}
+
+// NotifierFromContext returns the Notifier value stored in ctx, if any.
+func NotifierFromContext(ctx context.Context) (Notifier, bool) {
+ n, ok := ctx.Value(notifierKey{}).(Notifier)
+ return n, ok
+}
+
// Subscription defines the interface for objects that can notify subscribers
type Subscription interface {
// Inform client of an event
diff --git a/rpc/notification_test.go b/rpc/notification_test.go
index cd05d73fe..1bcede177 100644
--- a/rpc/notification_test.go
+++ b/rpc/notification_test.go
@@ -36,7 +36,7 @@ func (s *NotificationTestService) Unsubscribe(subid string) {
}
func (s *NotificationTestService) SomeSubscription(ctx context.Context, n, val int) (Subscription, error) {
- notifier, supported := ctx.Value(NotifierContextKey).(Notifier)
+ notifier, supported := NotifierFromContext(ctx)
if !supported {
return nil, ErrNotificationsUnsupported
}
diff --git a/rpc/server.go b/rpc/server.go
index cf90eba02..001107a1b 100644
--- a/rpc/server.go
+++ b/rpc/server.go
@@ -32,9 +32,6 @@ import (
const (
stopPendingRequestTimeout = 3 * time.Second // give pending requests stopPendingRequestTimeout the time to finish when the server is stopped
- // NotifierContextKey is the key where the notifier associated with the codec is stored in the context
- NotifierContextKey = 1
-
notificationBufferSize = 10000 // max buffered notifications before codec is closed
DefaultIPCApis = "admin,eth,debug,miner,net,shh,txpool,personal,web3"
@@ -171,7 +168,7 @@ func (s *Server) serveRequest(codec ServerCodec, singleShot bool, options CodecO
// to send notification to clients. It is thight to the codec/connection. If the
// connection is closed the notifier will stop and cancels all active subscriptions.
if options&OptionSubscriptions == OptionSubscriptions {
- ctx = context.WithValue(ctx, NotifierContextKey, newBufferedNotifier(codec, notificationBufferSize))
+ ctx = context.WithValue(ctx, notifierKey{}, newBufferedNotifier(codec, notificationBufferSize))
}
s.codecsMu.Lock()
if atomic.LoadInt32(&s.run) != 1 { // server stopped
@@ -275,7 +272,7 @@ func (s *Server) handle(ctx context.Context, codec ServerCodec, req *serverReque
if req.isUnsubscribe { // cancel subscription, first param must be the subscription id
if len(req.args) >= 1 && req.args[0].Kind() == reflect.String {
- notifier, supported := ctx.Value(NotifierContextKey).(*bufferedNotifier)
+ notifier, supported := NotifierFromContext(ctx)
if !supported { // interface doesn't support subscriptions (e.g. http)
return codec.CreateErrorResponse(&req.id, &callbackError{ErrNotificationsUnsupported.Error()}), nil
}
@@ -298,8 +295,8 @@ func (s *Server) handle(ctx context.Context, codec ServerCodec, req *serverReque
// active the subscription after the sub id was successful sent to the client
activateSub := func() {
- notifier, _ := ctx.Value(NotifierContextKey).(*bufferedNotifier)
- notifier.activate(subid)
+ notifier, _ := NotifierFromContext(ctx)
+ notifier.(*bufferedNotifier).activate(subid)
}
return codec.CreateResponse(req.id, subid), activateSub