Hi,

Here is how the TP4 bytecode submission infrastructure is looking.

In TP3, TraversalSource maintained the “pre-compilation” of strategies, 
database connectivity, etc. This was not smart for the following reasons:

        1. It assumed the traversal would execute on the same machine that it 
was created on.
        2. We had to make an explicit distinction between local and remote 
execution via RemoteStrategy.
        3. RemoteStrategy passes an excessive amount of data over the wire on 
each traversal submission (the source instructions!).
        4. RemoteStrategy is bug prone with traversal inspection and 
RemoteStep, etc.

 In TP4, we are now going to assume that Bytecode (a traversal) is always 
submitted somewhere and this “somewhere" could be local or remote. This 
“somewhere” must implement the Machine interface.

        
https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/Machine.java

Machine makes explicit the TP4 communication protocol. The only objects being 
transmitted are either Bytecode or Traversers. Simple.

Here is an example using LocalMachine:

Machine machine = LocalMachine.open();
TraversalSource g = 
Gremlin.traversal(machine).withProcessor(…).withStructure(…).withStrategy(…)

The first time a traversal is generated from g, the Bytecode source 
instructions are registered with the machine.

        
https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/language/gremlin/src/main/java/org/apache/tinkerpop/language/gremlin/TraversalSource.java#L99-L104
 
<https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/language/gremlin/src/main/java/org/apache/tinkerpop/language/gremlin/TraversalSource.java#L99-L104>

The intention is that, on registration, the Machine will pre-compile the source 
instructions (sort strategies, ensure processor and structure 
setup/connectivity). Machine.register() returns a new Bytecode which contains 
the registration information for future lookup. This registration information 
is Machine-specific and can even be nothing!

        
https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/BasicMachine.java#L37-L39
 
<https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/BasicMachine.java#L37-L39>

However, more intelligently, LocalMachine maintains a 
Map<UUID,SourceCompilation> which maintains pre-compiled source instructions.

        
https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/LocalMachine.java#L47-L62
 
<https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/LocalMachine.java#L47-L62>

Now when bytecode (containing instructions for execution) is submitted to 
LocalMachine, it will lookup the registered UUID and if it exists, use the 
pre-compiled source code. As you can see, a pre-compilation has everything 
staged and ready for use.

        
https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java
 
<https://github.com/apache/tinkerpop/blob/596caf3ab82f3b15c2c343af87be6d03f26d6d6e/java/machine/machine-core/src/main/java/org/apache/tinkerpop/machine/bytecode/compiler/SourceCompilation.java>

For remote execution, we simply need RemoteMachine which would serialize and 
deserialize Bytecode and Traversers to some RemoteMachineServer (or some 
provider-specific server able to use the basic protocol we will develop). For 
instance:

Machine machine = RemoteMachine.open(Map.of(“ip”,”127.0.0.1”,”port”,”32”))
TraversalSource g = 
Gremlin.traversal(machine).withProcessor(…).withStructure(…).withStrategy(…)

// prior to V(), the bytecode is registered and a new “registration” bytecode 
is returned and appended with V and count instructions.
g.V().count()

// no registration occurs as the TraversalSource hasn’t changed, the bytecode 
is simply submitted.
g.V().out().count() 

// the remote registration is removed
g.close() 

// a new registration occurs
g = g.withStrategy(…)
g.V().drop()

// the remote registration is removed
g.close() 

Tada!

WDYT?,
Marko.

http://rredux.com <http://rredux.com/>




Reply via email to