/
options.go
147 lines (124 loc) · 5.18 KB
/
options.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// 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 options defines common options recognized by vanadium implementations.
//
// Below are the common options required of all vanadium implementations. Let's
// say we have functions MyFuncA and MyFuncB in package demo:
//
// package demo
// func MyFuncA(a, b, c int, opts ...MyFuncAOpt)
// func MyFuncB(opts ...MyFuncBOpt)
//
// type MyFuncAOpt interface {
// DemoMyFuncAOpt()
// }
// type MyFuncBOpt interface {
// DemoMyFuncBOpt()
// }
//
// The MyFuncAOpt interface is used solely to constrain the types of options
// that MyFuncA accepts, and ditto for MyFuncBOpt and MyFuncB. In order to
// enable an option to be accepted by a particular function, you simply add a
// no-op function definition with the appropriate name. An example:
//
// type Foo int
// func (Foo) DemoMyFuncAOpt() {}
// func (Foo) DemoMyFuncBOpt() {}
//
// type Bar string
// func (Bar) DemoMyFuncBOpt() {}
//
// Foo is accepted by both demo.MyFuncA and demo.MyFuncB, while Bar is only
// accepted by demo.MyFuncB. The methods defined for each option essentially
// act as annotations telling us which functions will accept them.
//
// Go stipulates that methods may only be attached to named types, and the type
// may not be an interface. E.g.
//
// // BAD: can't attach methods to named interfaces.
// type Bad interface{}
// func (Bad) DemoMyFuncAOpt() {}
//
// // GOOD: wrap the interface in a named struct.
// type Good struct { val interface{} }
//
// func (Good) DemoMyFuncAOpt() {}
//
// These options can then be passed to the function as so:
// MyFuncA(a, b, c, Foo(1), Good{object})
package options
import (
"time"
"v.io/v23/naming"
"v.io/v23/security"
)
// ServerPeers is the set of peers to whom a process (a "server") accepting
// network connections must reveal its blessings.
//
// If this option is not provided, then the server's blessings will be revealed
// to all processes (clients) from whom the server accepts network connections.
//
// NOTE: This is an experimental option and may go away at any time.
type ServerPeers []security.BlessingPattern
func (ServerPeers) RPCServerOpt() {}
// ServerAuthorizer encapsulates the authorization policy used by a client to
// authorize the end server of an RPC.
//
// This policy is applied before the client sends information about itself
// (public key, blessings, the RPC request) to the server. Thus, if a server
// does not satisfy this policy then the client will abort the request.
//
// Authorization of other servers communicated with in the process of
// contacting the end server are controlled by other options, like
// NameResolutionAuthorizer.
//
// Runtime implementations are expected to use security.EndpointAuthorizer
// if no explicit ServerAuthorizer has been provided for the call.
type ServerAuthorizer struct{ security.Authorizer }
func (ServerAuthorizer) RPCCallOpt() {}
// NameResolutionAuthorizer encapsulates the authorization policy used by a
// client to authorize mounttable servers before sending them a name resolution
// request. By specifying this policy, clients avoid revealing the names they
// are interested in resolving to unauthorized mounttables.
//
// If no such option is provided, then runtime implementations are expected to
// default to security.EndpointAuthorizer.
type NameResolutionAuthorizer struct{ security.Authorizer }
func (NameResolutionAuthorizer) RPCCallOpt() {}
func (NameResolutionAuthorizer) NSOpt() {}
// Preresolved specifies that the RPC call should not further Resolve the name.
// If a MountEntry is provided, use it. Otherwise use the name passed in the
// RPC call. If the name is relative, it will be made global using
// the roots in the namespace.
type Preresolved struct {
Resolution *naming.MountEntry
}
func (Preresolved) RPCCallOpt() {}
func (Preresolved) NSOpt() {}
// Create a server that will be used to serve a MountTable. This server
// cannot be used for any other purpose.
type ServesMountTable bool
func (ServesMountTable) RPCServerOpt() {}
// LameDuckTimeout specifies the time to wait for all server operations to complete after Stop is called.
type LameDuckTimeout time.Duration
func (LameDuckTimeout) RPCServerOpt() {}
// Create a server that will be used to serve a leaf service.
type IsLeaf bool
func (IsLeaf) RPCServerOpt() {}
// When NoRetry is specified, the client will not retry calls that fail but would
// normally be retried.
type NoRetry struct{}
func (NoRetry) NSOpt() {}
func (NoRetry) RPCCallOpt() {}
// ChannelTimeout is the amount of time before we notice that a channel is
// not responsive and close it. Note that ChannelTimeout(0) is the same as
// not setting a timeout.
type ChannelTimeout time.Duration
func (ChannelTimeout) RPCCallOpt() {}
func (ChannelTimeout) RPCServerOpt() {}
// ConnectionTimeout is the amount of time we will try establishing a connection
// to the remote end during an RPC. Zero means only use cached connections and
// do not attempt to retry if no connection exists in the cache.
type ConnectionTimeout time.Duration
func (ConnectionTimeout) RPCCallOpt() {}