blob: 4be4daf94251202b329ced350ceee07663e47dbc [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package rpc
import (
"time"
"v.io/v23/context"
"v.io/v23/naming"
"v.io/v23/options"
"v.io/v23/rpc"
"v.io/x/ref/lib/apilog"
)
// PreferredProtocols instructs the Runtime implementation to select
// endpoints with the specified protocols when a Client makes a call
// and to order them in the specified order.
type PreferredProtocols []string
func (PreferredProtocols) RPCClientOpt() {
defer apilog.LogCall(nil)(nil) // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT
}
// This option is used to sort and filter the endpoints when resolving the
// proxy name from a mounttable.
type PreferredServerResolveProtocols []string
func (PreferredServerResolveProtocols) RPCServerOpt() {
defer apilog.LogCall(nil)(nil) // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT
}
// ReservedNameDispatcher specifies the dispatcher that controls access
// to framework managed portion of the namespace.
type ReservedNameDispatcher struct {
Dispatcher rpc.Dispatcher
}
func (ReservedNameDispatcher) RPCServerOpt() {
defer apilog.LogCall(nil)(nil) // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT
}
// IdleConnectionExpiry is the amount of the time after which the connection cache
// will close idle connections.
type IdleConnectionExpiry time.Duration
func (IdleConnectionExpiry) RPCClientOpt() {
defer apilog.LogCall(nil)(nil) // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT
}
func (IdleConnectionExpiry) RPCServerOpt() {
defer apilog.LogCall(nil)(nil) // gologcop: DO NOT EDIT, MUST BE FIRST STATEMENT
}
type connectionOpts struct {
connDeadline time.Time
channelTimeout time.Duration
useOnlyCached bool
noRetry bool
}
func getConnectionOptions(ctx *context.T, opts []rpc.CallOpt) *connectionOpts {
now := time.Now()
var copts connectionOpts
for _, o := range opts {
switch t := o.(type) {
case options.ConnectionTimeout:
if dur := time.Duration(t); dur == 0 {
copts.useOnlyCached = true
} else {
// Use the minimum of all the timeouts passed in.
if dl := now.Add(dur); dl.Before(copts.connDeadline) || copts.connDeadline.IsZero() {
copts.connDeadline = dl
}
}
case options.ChannelTimeout:
// Use the minimum channel timeout.
if dur := time.Duration(t); dur < copts.channelTimeout || copts.channelTimeout == 0 {
copts.channelTimeout = time.Duration(t)
}
case options.NoRetry:
copts.noRetry = true
}
}
// If the context deadline is sooner than connection deadline, use it instead.
if dl, hasDl := ctx.Deadline(); hasDl && (dl.Before(copts.connDeadline) || copts.connDeadline.IsZero()) {
copts.connDeadline = dl
}
// If no deadline has been set yet, use the default call timeout.
if copts.connDeadline.IsZero() {
copts.connDeadline = now.Add(defaultCallTimeout)
}
return &copts
}
func getNoNamespaceOpt(opts []rpc.CallOpt) bool {
for _, o := range opts {
switch o.(type) {
case options.Preresolved:
return true
}
}
return false
}
func getNamespaceOpts(opts []rpc.CallOpt) (resolveOpts []naming.NamespaceOpt) {
for _, o := range opts {
if r, ok := o.(naming.NamespaceOpt); ok {
resolveOpts = append(resolveOpts, r)
}
}
return
}