Skip to content
Snippets Groups Projects
rpcinvocation.go 6.08 KiB
Newer Older
AlexStocks's avatar
AlexStocks committed
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
fangyincheng's avatar
fangyincheng committed

vito.he's avatar
vito.he committed
package invocation
fangyincheng's avatar
fangyincheng committed

import (
	"reflect"
fangyincheng's avatar
fangyincheng committed
)

import (
fangyincheng's avatar
fangyincheng committed
)

flycash's avatar
flycash committed
// ///////////////////////////
fangyincheng's avatar
fangyincheng committed
// Invocation Impletment of RPC
flycash's avatar
flycash committed
// ///////////////////////////
fangyincheng's avatar
fangyincheng committed
// todo: is it necessary to separate fields of consumer(provider) from RPCInvocation
邹毅贤's avatar
邹毅贤 committed
// nolint
fangyincheng's avatar
fangyincheng committed
type RPCInvocation struct {
xujianhai666's avatar
xujianhai666 committed
	methodName      string
	parameterTypes  []reflect.Type
	parameterValues []reflect.Value
xujianhai666's avatar
xujianhai666 committed
	arguments       []interface{}
	reply           interface{}
	callBack        interface{}
	attachments     map[string]string
cvictory's avatar
cvictory committed
	// Refer to dubbo 2.7.6.  It is different from attachment. It is used in internal process.
	attributes map[string]interface{}
	invoker    protocol.Invoker
	lock       sync.RWMutex
fangyincheng's avatar
fangyincheng committed
}

邹毅贤's avatar
邹毅贤 committed
// NewRPCInvocation creates a RPC invocation.
func NewRPCInvocation(methodName string, arguments []interface{}, attachments map[string]string) *RPCInvocation {
fangyincheng's avatar
fangyincheng committed
	return &RPCInvocation{
		methodName:  methodName,
		arguments:   arguments,
fangyincheng's avatar
fangyincheng committed
		attachments: attachments,
		attributes:  make(map[string]interface{}, 8),
fangyincheng's avatar
fangyincheng committed
	}
}

邹毅贤's avatar
邹毅贤 committed
// NewRPCInvocationWithOptions creates a RPC invocation with @opts.
aliiohs's avatar
aliiohs committed
func NewRPCInvocationWithOptions(opts ...option) *RPCInvocation {
	invo := &RPCInvocation{}
	for _, opt := range opts {
		opt(invo)
	if invo.attributes == nil {
		invo.attributes = make(map[string]interface{})
	}
aliiohs's avatar
aliiohs committed
	return invo
邹毅贤's avatar
邹毅贤 committed
// MethodName gets RPC invocation method name.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) MethodName() string {
	return r.methodName
}

邹毅贤's avatar
邹毅贤 committed
// ParameterTypes gets RPC invocation parameter types.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) ParameterTypes() []reflect.Type {
	return r.parameterTypes
}

邹毅贤's avatar
邹毅贤 committed
// ParameterValues gets RPC invocation parameter values.
func (r *RPCInvocation) ParameterValues() []reflect.Value {
	return r.parameterValues
}

邹毅贤's avatar
邹毅贤 committed
// Arguments gets RPC arguments.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) Arguments() []interface{} {
	return r.arguments
}

邹毅贤's avatar
邹毅贤 committed
// Reply gets response of RPC request.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) Reply() interface{} {
	return r.reply
}

邹毅贤's avatar
邹毅贤 committed
// SetReply sets response of RPC request.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) SetReply(reply interface{}) {
	r.reply = reply
}

邹毅贤's avatar
邹毅贤 committed
// Attachments gets all attachments of RPC.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) Attachments() map[string]string {
	return r.attachments
}

邹毅贤's avatar
邹毅贤 committed
// AttachmentsByKey gets RPC attachment by key , if nil then return default value.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) AttachmentsByKey(key string, defaultValue string) string {
	r.lock.RLock()
	defer r.lock.RUnlock()
fangyincheng's avatar
fangyincheng committed
	if r.attachments == nil {
		return defaultValue
	}
	value, ok := r.attachments[key]
	if ok {
		return value
	}
	return defaultValue
}

邹毅贤's avatar
邹毅贤 committed
// Attributes gets all attributes of RPC.
cvictory's avatar
cvictory committed
func (r *RPCInvocation) Attributes() map[string]interface{} {
	return r.attributes
}

邹毅贤's avatar
邹毅贤 committed
// AttributeByKey gets attribute by @key. If it is not exist, it will return default value.
cvictory's avatar
cvictory committed
func (r *RPCInvocation) AttributeByKey(key string, defaultValue interface{}) interface{} {
	r.lock.RLock()
	defer r.lock.RUnlock()
	value, ok := r.attributes[key]
	if ok {
		return value
	}
	return defaultValue
}

邹毅贤's avatar
邹毅贤 committed
// SetAttachments sets attribute by @key and @value.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) SetAttachments(key string, value string) {
	r.lock.Lock()
	defer r.lock.Unlock()
fangyincheng's avatar
fangyincheng committed
	if r.attachments == nil {
		r.attachments = make(map[string]string)
	}
	r.attachments[key] = value
}

邹毅贤's avatar
邹毅贤 committed
// SetAttribute sets attribute by @key and @value.
func (r *RPCInvocation) SetAttribute(key string, value interface{}) {
	r.lock.Lock()
	defer r.lock.Unlock()
	r.attributes[key] = value
}

邹毅贤's avatar
邹毅贤 committed
// Invoker gets the invoker in current context.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) Invoker() protocol.Invoker {
	return r.invoker
}

// nolint
func (r *RPCInvocation) SetInvoker(invoker protocol.Invoker) {
	r.invoker = invoker
}

邹毅贤's avatar
邹毅贤 committed
// CallBack sets RPC callback method.
func (r *RPCInvocation) CallBack() interface{} {
	return r.callBack
}

邹毅贤's avatar
邹毅贤 committed
// SetCallBack sets RPC callback method.
fangyincheng's avatar
fangyincheng committed
func (r *RPCInvocation) SetCallBack(c interface{}) {
	r.callBack = c
}
fangyincheng's avatar
fangyincheng committed

flycash's avatar
flycash committed
// /////////////////////////
// option
flycash's avatar
flycash committed
// /////////////////////////

type option func(invo *RPCInvocation)

邹毅贤's avatar
邹毅贤 committed
// WithMethodName creates option with @methodName.
func WithMethodName(methodName string) option {
	return func(invo *RPCInvocation) {
		invo.methodName = methodName
	}
}

邹毅贤's avatar
邹毅贤 committed
// WithParameterTypes creates option with @parameterTypes.
func WithParameterTypes(parameterTypes []reflect.Type) option {
	return func(invo *RPCInvocation) {
		invo.parameterTypes = parameterTypes
	}
}

邹毅贤's avatar
邹毅贤 committed
// WithParameterValues creates option with @parameterValues
func WithParameterValues(parameterValues []reflect.Value) option {
	return func(invo *RPCInvocation) {
		invo.parameterValues = parameterValues
	}
}

邹毅贤's avatar
邹毅贤 committed
// WithArguments creates option with @arguments function.
func WithArguments(arguments []interface{}) option {
	return func(invo *RPCInvocation) {
		invo.arguments = arguments
	}
}

邹毅贤's avatar
邹毅贤 committed
// WithReply creates option with @reply function.
func WithReply(reply interface{}) option {
	return func(invo *RPCInvocation) {
		invo.reply = reply
	}
}

邹毅贤's avatar
邹毅贤 committed
// WithCallBack creates option with @callback function.
func WithCallBack(callBack interface{}) option {
	return func(invo *RPCInvocation) {
		invo.callBack = callBack
	}
}

邹毅贤's avatar
邹毅贤 committed
// WithAttachments creates option with @attachments.
func WithAttachments(attachments map[string]string) option {
	return func(invo *RPCInvocation) {
		invo.attachments = attachments
	}
fangyincheng's avatar
fangyincheng committed
}
vito.he's avatar
vito.he committed

邹毅贤's avatar
邹毅贤 committed
// WithInvoker creates option with @invoker.
func WithInvoker(invoker protocol.Invoker) option {
	return func(invo *RPCInvocation) {
		invo.invoker = invoker
	}
vito.he's avatar
vito.he committed
}