-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement graph binary protocol #217
base: master
Are you sure you want to change the base?
Changes from 53 commits
153b6cd
076949f
cbaa2bf
946d132
dce5400
e426d0d
6cfc168
97a3de6
0a39163
36a9989
c810c07
6de4156
5330d8f
ee6086f
f273b14
5b5108c
678792f
4ca0eb5
455e329
4a42319
32b47ac
815767a
753dbf7
0368454
54b2457
35d22ed
490e925
69da91e
6db1750
e570908
f2880a0
2492d09
e9a0c6d
baccdd5
6626be3
d07679e
fe2c0de
2083461
e2cbd2c
fb3bf91
1bd393d
0bd9f9a
ae34c00
aacd284
f54ea77
85a58f1
a1bbe79
b4d9015
5a4931b
97ca6c1
2d2b13a
081ad4e
5fb1adb
03cb90a
49799e2
766f045
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# Copyright 2019 JanusGraph Authors | ||
# | ||
# Licensed 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. | ||
|
||
host: 0.0.0.0 | ||
port: 8182 | ||
evaluationTimeout: 30000 | ||
channelizer: org.apache.tinkerpop.gremlin.server.channel.WebSocketChannelizer | ||
graphManager: org.janusgraph.graphdb.management.JanusGraphManager | ||
graphs: { | ||
graph: conf/janusgraph-inmemory.properties | ||
} | ||
scriptEngines: { | ||
gremlin-groovy: { | ||
plugins: { org.janusgraph.graphdb.tinkerpop.plugin.JanusGraphGremlinPlugin: {}, | ||
org.apache.tinkerpop.gremlin.server.jsr223.GremlinServerGremlinPlugin: {}, | ||
org.apache.tinkerpop.gremlin.tinkergraph.jsr223.TinkerGraphGremlinPlugin: {}, | ||
org.apache.tinkerpop.gremlin.jsr223.ImportGremlinPlugin: {classImports: [java.lang.Math], methodImports: [java.lang.Math#*]}, | ||
org.apache.tinkerpop.gremlin.jsr223.ScriptFileGremlinPlugin: {files: [scripts/empty-sample.groovy]}}}} | ||
serializers: | ||
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} | ||
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }} | ||
Comment on lines
+31
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By default JanusGraph doesn't have GraphBinary enabled so the custom vertex id tests were failing as the serializer wasn't enabled. This config enables them here and the config is then mounted into the needed spot in the docker-compose file |
||
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} | ||
# Older serialization versions for backwards compatibility: | ||
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistry] }} | ||
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV1, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }} | ||
- { className: org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1, config: { ioRegistries: [org.janusgraph.graphdb.tinkerpop.JanusGraphIoRegistryV1d0] }} | ||
processors: | ||
- { className: org.apache.tinkerpop.gremlin.server.op.session.SessionOpProcessor, config: { sessionTimeout: 28800000 }} | ||
- { className: org.apache.tinkerpop.gremlin.server.op.traversal.TraversalOpProcessor, config: { cacheExpirationTime: 600000, cacheMaxSize: 1000 }} | ||
metrics: { | ||
consoleReporter: {enabled: true, interval: 180000}, | ||
csvReporter: {enabled: true, interval: 180000, fileName: /tmp/gremlin-server-metrics.csv}, | ||
jmxReporter: {enabled: true}, | ||
slf4jReporter: {enabled: true, interval: 180000}, | ||
graphiteReporter: {enabled: false, interval: 180000}} | ||
maxInitialLineLength: 4096 | ||
maxHeaderSize: 8192 | ||
maxChunkSize: 8192 | ||
maxContentLength: 65536 | ||
maxAccumulationBufferComponents: 1024 | ||
resultIterationBatchSize: 64 | ||
writeBufferLowWaterMark: 32768 | ||
writeBufferHighWaterMark: 65536 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,8 +69,10 @@ tokio = { version = "1", optional=true, features = ["full"] } | |
features = ["serde", "v4"] | ||
version = "1.1.2" | ||
|
||
|
||
|
||
[dev-dependencies] | ||
rstest = "0.23.0" | ||
rstest_reuse = "0.7.0" | ||
serial_test = "3.1.1" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Each test generally used labels to prevent tests from stepping on each other. However the parameterized serializers will run concurrently. So I used |
||
|
||
[[example]] | ||
name = "traversal_async" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In general all the changes here and in the blocking client are to encapsulate the differences between the serializers so the binary protocol can be easily called from the same code path as the graphson protocols |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
use crate::{GremlinError, GremlinResult, WebSocketOptions}; | ||
use crate::{GremlinError, GremlinResult, IoProtocol}; | ||
|
||
use crate::connection::ConnectionOptions; | ||
|
||
|
@@ -90,7 +90,7 @@ | |
_scts: &mut dyn Iterator<Item = &[u8]>, | ||
_ocsp_response: &[u8], | ||
_now: SystemTime, | ||
) -> Result<rustls::client::ServerCertVerified, rustls::TLSError> { | ||
Check warning on line 93 in gremlin-client/src/aio/connection.rs GitHub Actions / build_and_test (ubuntu-latest, stable, 3.5.7)
|
||
Ok(rustls::client::ServerCertVerified::assertion()) | ||
} | ||
} | ||
|
@@ -165,7 +165,7 @@ | |
|
||
sender_loop(sink, requests.clone(), receiver); | ||
|
||
receiver_loop(stream, requests.clone(), sender.clone()); | ||
receiver_loop(stream, requests.clone(), sender.clone(), opts.deserializer); | ||
|
||
Ok(Conn { | ||
sender, | ||
|
@@ -266,6 +266,7 @@ | |
mut stream: SplitStream<WSStream>, | ||
requests: Arc<Mutex<HashMap<Uuid, Sender<GremlinResult<Response>>>>>, | ||
mut sender: Sender<Cmd>, | ||
deserializer: IoProtocol, | ||
) { | ||
task::spawn(async move { | ||
loop { | ||
|
@@ -283,10 +284,24 @@ | |
} | ||
Some(Ok(item)) => match item { | ||
Message::Binary(data) => { | ||
let response: Response = serde_json::from_slice(&data).unwrap(); | ||
let response = deserializer | ||
.read_response(data) | ||
.expect("Unable to parse message"); | ||
let mut guard = requests.lock().await; | ||
|
||
//GraphBinary permits a null response request id, so in lieu of a request id assume | ||
//a single entry in the requests to be the one we should respond to given connection | ||
//multiplexing isn't currently implemented | ||
Comment on lines
+292
to
+294
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least on the GraphBinary side its documented that request Id can come back null. This seemed like the best means to try to mitigate that when it happens. Since connection multiplexing isn't in play, it seems like this should be an okay tradeoff. The alternative would be removing the whole |
||
let request_id = response.request_id.unwrap_or_else(|| { | ||
if guard.len() == 1 { | ||
guard.keys().next().expect("Should have had only 1 key").clone() | ||
} else { | ||
panic!("Request response without request id was received, but there isn't only 1 request currently submitted"); | ||
} | ||
}); | ||
|
||
if response.status.code != 206 { | ||
let item = guard.remove(&response.request_id); | ||
let item = guard.remove(&request_id); | ||
drop(guard); | ||
if let Some(mut s) = item { | ||
match s.send(Ok(response)).await { | ||
|
@@ -295,7 +310,7 @@ | |
}; | ||
} | ||
} else { | ||
let item = guard.get_mut(&response.request_id); | ||
let item = guard.get_mut(&request_id); | ||
if let Some(s) = item { | ||
match s.send(Ok(response)).await { | ||
Ok(_r) => {} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added derive flag to tests, notice the derive tests weren't being ran