Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit ecf165d

Browse files
committedSep 18, 2019
Soft automatic schema reload
Now client keeps actual schema metadata and sends schemaId header to be checked against current Tarantool schema version. If client version mismatches DB version client does schema reloading in the background. Client operation interface was reworked in scope of support not only number identifiers for spaces and indexes but also their string names. Closes: #7, #137
1 parent 08e37a2 commit ecf165d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+2414
-438
lines changed
 

‎README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,52 @@ all the results, you could override this:
130130
protected void complete(TarantoolPacket packet, TarantoolOp<?> future);
131131
```
132132

133+
## String space/index resolution
134+
135+
Each operation that requires space or index to be executed, can work with
136+
number ID as well as string name of a space or an index.
137+
Assume, we have `my_space` space with space ID `512` and its primary index
138+
`primary` with index ID `0`. Then, for instance, `select` operations can be
139+
performed using their names:
140+
141+
```java
142+
client.syncOps().select(512, 0, Collections.singletonList(1), 0, 1, Iterator.EQ);
143+
// or using more convenient way
144+
client.syncOps().select("my_space", "primary", Collections.singletonList(1), 0, 1, Iterator.EQ);
145+
```
146+
147+
Because _iproto_ has not yet supported string spaces and indexes, a client caches current server
148+
schema in memory. The client relies on protocol SCHEMA_ID and sends each request with respect to
149+
cached schema version. The schema is used primarily to resolve string names of spaces or indexes
150+
against its integer IDs.
151+
152+
### Schema update
153+
154+
1. Just after a (re-)connection to the Tarantool instance.
155+
The client cannot guarantee that new instance is the same and has same schema,
156+
thus, the client drops the cached schema and fetches new one.
157+
2. Receiving a schema version error as a response to our request.
158+
It's possible some request can be rejected by server because of schema
159+
mismatching between client and server. In this case the schema will be
160+
reloaded and the refused request will be resent using the updated schema
161+
version.
162+
3. Sending a DDL request and receiving a new version in a response.
163+
4. Sending a request against a non-existent space/index name.
164+
The client cannot exactly know whether name was not found because of
165+
it does not exist or it has not the latest schema version.
166+
167+
### Schema support caveats
168+
169+
1. Each schema reloading requires at least two extra requests to fetch spaces and
170+
indexes metadata respectively. There is also a ping request followed by reloading
171+
of the schema to check whether the client has outdated version (see point 4 in
172+
Schema update section).
173+
2. In some circumstance, requests can be rejected several times until both client's
174+
and server's versions matches. It may take significant amount of time or even be
175+
a cause of request timeout.
176+
3. The client guarantees an order of synchronous requests per thread. Other cases such
177+
as asynchronous or multi-threaded requests may be out of order before the execution.
178+
133179
## Spring NamedParameterJdbcTemplate usage example
134180

135181
The JDBC driver uses `TarantoolClient` implementation to provide a communication with server.
Lines changed: 167 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,204 @@
11
package org.tarantool;
22

3+
import static org.tarantool.RequestArguments.cacheLookupValue;
4+
import static org.tarantool.RequestArguments.value;
35

4-
public abstract class AbstractTarantoolOps<Space, Tuple, Operation, Result>
5-
implements TarantoolClientOps<Space, Tuple, Operation, Result> {
6+
import org.tarantool.schema.TarantoolSchemaMeta;
7+
8+
import java.util.List;
9+
10+
public abstract class AbstractTarantoolOps<Result>
11+
implements TarantoolClientOps<List<?>, Object, Result> {
612

713
private Code callCode = Code.CALL;
814

9-
protected abstract Result exec(Code code, Object... args);
15+
protected abstract Result exec(TarantoolRequest request);
16+
17+
protected abstract TarantoolSchemaMeta getSchemaMeta();
18+
19+
public Result select(Integer space, Integer index, List<?> key, int offset, int limit, Iterator iterator) {
20+
return select(space, index, key, offset, limit, iterator.getValue());
21+
}
1022

11-
public Result select(Space space, Space index, Tuple key, int offset, int limit, Iterator iterator) {
23+
@Override
24+
public Result select(String space, String index, List<?> key, int offset, int limit, Iterator iterator) {
1225
return select(space, index, key, offset, limit, iterator.getValue());
1326
}
1427

15-
public Result select(Space space, Space index, Tuple key, int offset, int limit, int iterator) {
28+
@Override
29+
public Result select(Integer space, Integer index, List<?> key, int offset, int limit, int iterator) {
30+
return exec(
31+
new TarantoolRequest(
32+
Code.SELECT,
33+
value(Key.SPACE), value(space),
34+
value(Key.INDEX), value(index),
35+
value(Key.KEY), value(key),
36+
value(Key.ITERATOR), value(iterator),
37+
value(Key.LIMIT), value(limit),
38+
value(Key.OFFSET), value(offset)
39+
)
40+
);
41+
}
42+
43+
@Override
44+
public Result select(String space, String index, List<?> key, int offset, int limit, int iterator) {
45+
return exec(
46+
new TarantoolRequest(
47+
Code.SELECT,
48+
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
49+
value(Key.INDEX), cacheLookupValue(() -> getSchemaMeta().getSpaceIndex(space, index).getId()),
50+
value(Key.KEY), value(key),
51+
value(Key.ITERATOR), value(iterator),
52+
value(Key.LIMIT), value(limit),
53+
value(Key.OFFSET), value(offset)
54+
)
55+
);
56+
}
57+
58+
@Override
59+
public Result insert(Integer space, List<?> tuple) {
60+
return exec(new TarantoolRequest(
61+
Code.INSERT,
62+
value(Key.SPACE), value(space),
63+
value(Key.TUPLE), value(tuple)
64+
)
65+
);
66+
}
67+
68+
@Override
69+
public Result insert(String space, List<?> tuple) {
70+
return exec(
71+
new TarantoolRequest(
72+
Code.INSERT,
73+
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
74+
value(Key.TUPLE), value(tuple)
75+
)
76+
);
77+
}
78+
79+
@Override
80+
public Result replace(Integer space, List<?> tuple) {
81+
return exec(
82+
new TarantoolRequest(
83+
Code.REPLACE,
84+
value(Key.SPACE), value(space),
85+
value(Key.TUPLE), value(tuple)
86+
)
87+
);
88+
}
89+
90+
@Override
91+
public Result replace(String space, List<?> tuple) {
1692
return exec(
17-
Code.SELECT,
18-
Key.SPACE, space,
19-
Key.INDEX, index,
20-
Key.KEY, key,
21-
Key.ITERATOR, iterator,
22-
Key.LIMIT, limit,
23-
Key.OFFSET, offset
93+
new TarantoolRequest(
94+
Code.REPLACE,
95+
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
96+
value(Key.TUPLE), value(tuple)
97+
)
2498
);
2599
}
26100

27-
public Result insert(Space space, Tuple tuple) {
28-
return exec(Code.INSERT, Key.SPACE, space, Key.TUPLE, tuple);
101+
@Override
102+
public Result update(Integer space, List<?> key, Object... operations) {
103+
return exec(
104+
new TarantoolRequest(
105+
Code.UPDATE,
106+
value(Key.SPACE), value(space),
107+
value(Key.KEY), value(key),
108+
value(Key.TUPLE), value(operations)
109+
)
110+
);
29111
}
30112

31-
public Result replace(Space space, Tuple tuple) {
32-
return exec(Code.REPLACE, Key.SPACE, space, Key.TUPLE, tuple);
113+
@Override
114+
public Result update(String space, List<?> key, Object... operations) {
115+
return exec(
116+
new TarantoolRequest(
117+
Code.UPDATE,
118+
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
119+
value(Key.KEY), value(key),
120+
value(Key.TUPLE), value(operations)
121+
)
122+
);
123+
}
124+
125+
@Override
126+
public Result upsert(Integer space, List<?> key, List<?> defTuple, Object... operations) {
127+
return exec(
128+
new TarantoolRequest(
129+
Code.UPSERT,
130+
value(Key.SPACE), value(space),
131+
value(Key.KEY), value(key),
132+
value(Key.TUPLE), value(defTuple),
133+
value(Key.UPSERT_OPS), value(operations)
134+
)
135+
);
33136
}
34137

35-
public Result update(Space space, Tuple key, Operation... args) {
36-
return exec(Code.UPDATE, Key.SPACE, space, Key.KEY, key, Key.TUPLE, args);
138+
@Override
139+
public Result upsert(String space, List<?> key, List<?> defTuple, Object... operations) {
140+
return exec(
141+
new TarantoolRequest(
142+
Code.UPSERT,
143+
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
144+
value(Key.KEY), value(key),
145+
value(Key.TUPLE), value(defTuple),
146+
value(Key.UPSERT_OPS), value(operations)
147+
)
148+
);
37149
}
38150

39-
public Result upsert(Space space, Tuple key, Tuple def, Operation... args) {
40-
return exec(Code.UPSERT, Key.SPACE, space, Key.KEY, key, Key.TUPLE, def, Key.UPSERT_OPS, args);
151+
@Override
152+
public Result delete(Integer space, List<?> key) {
153+
return exec(
154+
new TarantoolRequest(
155+
Code.DELETE,
156+
value(Key.SPACE), value(space),
157+
value(Key.KEY), value(key)
158+
)
159+
);
41160
}
42161

43-
public Result delete(Space space, Tuple key) {
44-
return exec(Code.DELETE, Key.SPACE, space, Key.KEY, key);
162+
@Override
163+
public Result delete(String space, List<?> key) {
164+
return exec(
165+
new TarantoolRequest(
166+
Code.DELETE,
167+
value(Key.SPACE), cacheLookupValue(() -> getSchemaMeta().getSpace(space).getId()),
168+
value(Key.KEY), value(key)
169+
)
170+
);
45171
}
46172

173+
@Override
47174
public Result call(String function, Object... args) {
48-
return exec(callCode, Key.FUNCTION, function, Key.TUPLE, args);
175+
return exec(
176+
new TarantoolRequest(
177+
callCode,
178+
value(Key.FUNCTION), value(function),
179+
value(Key.TUPLE), value(args)
180+
)
181+
);
49182
}
50183

184+
@Override
51185
public Result eval(String expression, Object... args) {
52-
return exec(Code.EVAL, Key.EXPRESSION, expression, Key.TUPLE, args);
186+
return exec(
187+
new TarantoolRequest(
188+
Code.EVAL,
189+
value(Key.EXPRESSION), value(expression),
190+
value(Key.TUPLE), value(args)
191+
)
192+
);
53193
}
54194

195+
@Override
55196
public void ping() {
56-
exec(Code.PING);
197+
exec(new TarantoolRequest(Code.PING));
57198
}
58199

59200
public void setCallCode(Code callCode) {
60201
this.callCode = callCode;
61202
}
203+
62204
}

0 commit comments

Comments
 (0)
Please sign in to comment.