summaryrefslogtreecommitdiff
path: root/docs_oos/data/remote/remote.loopback.json
blob: 83c2ee8e761b21a5010cd9b4606a1a8bf9f9bca8 (plain)
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
{
	"format": 1,
	"id": "saw-remote-loopback",
	"kind": "class",
	"name": "remote",
	"namespace": "saw",
	"module": "remote",
	"header": "modules/remote/c++/remote_loopback_base.hpp",
	"is_special": true,
	"specializes": "saw-remote",
	"arguments": ["rmt::Loopback"],
	"brief_description": "In process backend.",
	"detailed_description": [
		[
			"The reference implementation every other backend is measured against. Nothing is serialized and nothing is copied across a boundary, so what remains is the bookkeeping every backend has to do."
		],
		[
			"Servers are registered under the address they listen on together with their class id, so a client asking for a schema on an address finds the one server which owns it."
		]
	],
	"examples": [
		{
			"title": "Serving an interface and calling it",
			"description": [
				[
					"The whole flow on one address: bring up the data servers, bind an interface to them, connect, call. Error handling is left out, but note that every error_or is kept in a named variable, because get_value hands back a reference into it."
				],
				[
					"The data servers have to exist before",
					{"name": "rpc_listen", "id": "saw-remote-loopback-rpc_listen"},
					"is called, since that is where the parameter and the answer live."
				]
			],
			"language": "cpp",
			"code": "using TestInterface = schema::Interface<\n\tschema::Member<schema::Function<schema::UInt32, schema::Int64>, \"foo\">\n>;\n\nevent_loop loop;\nwait_scope wait{loop};\n\nremote<rmt::Loopback> rmt;\n\nauto eo_addr = rmt.parse_address(0u);\nauto& addr = eo_addr.get_value();\n\n/// The transport layer, one server per schema the interface mentions.\nauto eo_u32_srv = rmt.data_listen<schema::UInt32, encode::Native>(*addr);\nauto eo_i64_srv = rmt.data_listen<schema::Int64, encode::Native>(*addr);\n\nauto iface = interface_factory<TestInterface, encode::Native>::create(\n\t[](data<schema::UInt32, encode::Native> input)\n\t\t-> error_or<data<schema::Int64, encode::Native>>\n\t{\n\t\tdata<schema::Int64, encode::Native> rv;\n\t\trv.set(input.get() * 2);\n\t\treturn rv;\n\t});\n\nauto eo_rpc_srv = rmt.rpc_listen<TestInterface, encode::Native>(*addr, std::move(iface));\n\n/// The overlay on top of it.\nauto cvr_client = rmt.rpc_connect<TestInterface, encode::Native>(*addr);\nauto eo_client = cvr_client.take();\nauto& client = eo_client.get_value();\n\ndata<schema::UInt32, encode::Native> inp{21};\n\nauto cvr_result = client.call<\"foo\">(std::move(inp));\nauto eo_result = cvr_result.take();\nauto& result = eo_result.get_value();\n\n/// The answer never left the server. result only knows the id it picked.\nauto eo_value = result.wait(wait);\n/// eo_value.get_value().get() == 42\n"
		}
	],
	"attributes": {
		"saw-remote-loopback-registered_data_servers_": {
			"id": "saw-remote-loopback-registered_data_servers_",
			"name": "registered_data_servers_",
			"type": ["std::map< key_t, ptr<", {"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > > >"],
			"visibility": "private",
			"brief_description": "Keyed by address id, schema hash and encoding hash."
		},
		"saw-remote-loopback-registered_rpc_servers_": {
			"id": "saw-remote-loopback-registered_rpc_servers_",
			"name": "registered_rpc_servers_",
			"type": ["std::map< key_t, ptr<", {"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > > >"],
			"visibility": "private",
			"brief_description": "Keyed by address id, interface hash and encoding hash."
		}
	},
	"functions": {
		"saw-remote-loopback-parse_address": {
			"id": "saw-remote-loopback-parse_address",
			"name": "parse_address",
			"type": ["error_or< own<", {"name": "remote_address", "id": "saw-remote_address-loopback"}, "< rmt::Loopback > > >"],
			"brief_description": "Resolves an address for the remote.",
			"parameters": [
				{
					"name": "id",
					"type": ["data< schema::UInt64 >"],
					"brief_description": "Identifier standing in for what a network address would be."
				}
			]
		},
		"saw-remote-loopback-data_listen": {
			"id": "saw-remote-loopback-data_listen",
			"name": "data_listen",
			"type": ["error_or< own<", {"name": "data_server", "id": "saw-data_server-loopback"}, "< Schema, Encode, rmt::Loopback > > >"],
			"brief_description": "Starts a data server for one schema on an address.",
			"detailed_description": [
				[
					"Fails with already_exists if a server for the same schema and encoding is already bound to that address. The returned server registers itself and stays reachable until it is destroyed."
				]
			],
			"templates": [
				{"name": "Schema", "kind": "type"},
				{"name": "Encode", "kind": "type"}
			],
			"parameters": [
				{"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}
			]
		},
		"saw-remote-loopback-data_connect": {
			"id": "saw-remote-loopback-data_connect",
			"name": "data_connect",
			"type": ["conveyor<", {"name": "data_client", "id": "saw-data_client-loopback"}, "< Schema, Encode, rmt::Loopback > >"],
			"brief_description": "Connects to a data server.",
			"detailed_description": [
				["Fails with not_found if nothing listens for that schema on that address."]
			],
			"templates": [
				{"name": "Schema", "kind": "type"},
				{"name": "Encode", "kind": "type"}
			],
			"parameters": [
				{"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}
			]
		},
		"saw-remote-loopback-rpc_listen": {
			"id": "saw-remote-loopback-rpc_listen",
			"name": "rpc_listen",
			"type": ["error_or< own<", {"name": "rpc_server", "id": "saw-rpc_server-loopback"}, "< Iface, Encode, rmt::Loopback > > >"],
			"brief_description": "Starts an rpc server for an interface on an address.",
			"detailed_description": [
				[
					"Every schema the interface mentions needs a data server on the same address beforehand, since that is where parameters and responses live. A missing one fails the call with not_found."
				]
			],
			"templates": [
				{"name": "Iface", "kind": "type"},
				{"name": "Encode", "kind": "type"}
			],
			"parameters": [
				{"name": "addr", "type": ["remote_address< rmt::Loopback > &"]},
				{
					"name": "iface",
					"type": ["typename rpc_server< Iface, Encode, rmt::Loopback >::InterfaceT"],
					"brief_description": "The implementations backing the interface."
				}
			]
		},
		"saw-remote-loopback-rpc_connect": {
			"id": "saw-remote-loopback-rpc_connect",
			"name": "rpc_connect",
			"type": ["conveyor<", {"name": "rpc_client", "id": "saw-rpc_client-loopback"}, "< Iface, Encode, rmt::Loopback > >"],
			"brief_description": "Connects to an rpc server.",
			"detailed_description": [
				["Defined in remote_loopback.hpp, since the client has to be a complete type at that point."]
			],
			"templates": [
				{"name": "Iface", "kind": "type"},
				{"name": "Encode", "kind": "type"}
			],
			"parameters": [
				{"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]}
			]
		},
		"saw-remote-loopback-register_data_server": {
			"id": "saw-remote-loopback-register_data_server",
			"name": "register_data_server",
			"type": ["error_or< void >"],
			"brief_description": "Internal. Called by a data server on construction.",
			"parameters": [
				{"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]},
				{"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]}
			]
		},
		"saw-remote-loopback-deregister_data_server": {
			"id": "saw-remote-loopback-deregister_data_server",
			"name": "deregister_data_server",
			"type": ["error_or< void >"],
			"brief_description": "Internal. Called by a data server on destruction.",
			"parameters": [
				{"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]},
				{"name": "srv", "type": [{"name": "i_data_server", "id": "saw-i_data_server"}, "< rmt::Loopback > &"]}
			]
		},
		"saw-remote-loopback-register_rpc_server": {
			"id": "saw-remote-loopback-register_rpc_server",
			"name": "register_rpc_server",
			"type": ["error_or< void >"],
			"brief_description": "Internal. Called by an rpc server on construction.",
			"parameters": [
				{"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]},
				{"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]}
			]
		},
		"saw-remote-loopback-deregister_rpc_server": {
			"id": "saw-remote-loopback-deregister_rpc_server",
			"name": "deregister_rpc_server",
			"type": ["error_or< void >"],
			"brief_description": "Internal. Called by an rpc server on destruction.",
			"parameters": [
				{"name": "addr", "type": ["const remote_address< rmt::Loopback > &"]},
				{"name": "srv", "type": [{"name": "i_rpc_server", "id": "saw-i_rpc_server"}, "< rmt::Loopback > &"]}
			]
		}
	}
}