You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tinkerpop.apache.org by "Stark Arya (Jira)" <ji...@apache.org> on 2019/09/23 11:42:00 UTC

[jira] [Comment Edited] (TINKERPOP-2299) Providing Flexible custom access capabilities by withSideEffect

    [ https://issues.apache.org/jira/browse/TINKERPOP-2299?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16935764#comment-16935764 ] 

Stark Arya edited comment on TINKERPOP-2299 at 9/23/19 11:41 AM:
-----------------------------------------------------------------

If user use script, they may use: g.withStrategies(DetachedElementStrategy.instance()) as string directly, it seems ok.

But if user use bytecode, the standard gremlin-driver / apache-tinkerpop-gremlin-console does not include DetachedElementStrategy which is provider special.

All above all, i think withStrategies currently lack of ability to provide sufficient flexibility.


was (Author: stark arya):
if user use script type, they may use: g.withStrategies(DetachedElementStrategy.instance()) as string, directly

but if user use bytecode, the standard gremlin-driver/apache-tinkerpop-gremlin-console not include DetachedElementStrategy.instance() which will disturb user.

all above all, i think withStrategies currently lack of ability to provide sufficient flexibility.

> Providing Flexible custom access capabilities by withSideEffect
> ---------------------------------------------------------------
>
>                 Key: TINKERPOP-2299
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP-2299
>             Project: TinkerPop
>          Issue Type: Improvement
>          Components: server
>            Reporter: Stark Arya
>            Priority: Major
>
> Graph Providers like AWS,  Alibaba  both use withSideEffect to provide vendor related abilities.  
> A simple example like:
> {noformat}
> g.withSideEffect("GDB#withStrategies","DetachedElementStrategy").otherSteps(){noformat}
> This will add SideEffectStrategy to traversalSource and apply later before traversal execute.  but it's logic is too simple(just put k, v into traversal.getSideEffects() and let traversal to use when executing ): 
> {noformat}
> @Override
> public void apply(final Traversal.Admin<?, ?> traversal) {
>     if (traversal.getParent() instanceof EmptyStep) {
>         this.sideEffects.forEach(triplet -> traversal.getSideEffects().register(triplet.getValue0(), triplet.getValue1(), triplet.getValue2()));
>     }
> }{noformat}
>  
> More general,  we need to provide a more powerful and flexible ability (some hooks ability) to allow provider‘s private functions be called,a sample i thinks looks like as follows:
> {code:java}
> /*
>  * (C)  2019-present Alibaba Group Holding Limited.
>  *
>  * This program is free software; you can redistribute it and/or modify
>  * it under the terms of the GNU General Public License version 2 as
>  * published by the Free Software Foundation.
>  *
>  * File:    WithSideEffectOptimizerStrategy.java
>  *
>  * Authors:
>  *   zhoujian <qi...@alibaba-inc.com>
>  *      2019-09-22 17:37 - initial release
>  */
> package com.alibaba.graphdb.core.optimize.strategy;
> import com.google.common.collect.Sets;
> import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
> import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
> import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SideEffectStrategy;
> import java.util.ArrayList;
> import java.util.Collection;
> import java.util.LinkedHashMap;
> import java.util.Map;
> import java.util.Set;
> import java.util.function.BiConsumer;
> /**
>  * gdb specific optimizer here
>  */
> public class WithSideEffectOptimizerStrategy extends  AbstractGraphDbTraversalStrategy {
>     private static final WithSideEffectOptimizerStrategy INSTANCE = new WithSideEffectOptimizerStrategy();
>     private final Collection<Optimizer> initials = new ArrayList<>();
>     public static WithSideEffectOptimizerStrategy instance() {
>         return INSTANCE;
>     }
>     public WithSideEffectOptimizerStrategy() {
>        initials.add(Optimizer.withStrategies.instance());
>     }
>     /**
>      *  (non-Javadoc)
>      * @see org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy#applyPrior()
>      */
>     @SuppressWarnings("unchecked")
>     @Override
>     public Set<Class<? extends ProviderOptimizationStrategy>> applyPrior() {
>         return (Set) Sets.newHashSet(SideEffectStrategy.class);
>     }
>     @Override
>     public void apply(final Traversal.Admin<?, ?> traversal) {
>         initials.forEach(optimizer -> optimizer.accept(traversal, optimizer.getAccessor()));
>     }
>     private enum  Optimizer implements BiConsumer<Traversal.Admin<?, ?>, String> {
>         withStrategies {
>             @Override
>             public Optimizer instance() {
>                 classMap.put(DetachedElementStrategy.class.getSimpleName(), DetachedElementStrategy.class.getCanonicalName());
>                 return this;
>             }
>             @Override
>             public String getAccessor () {
>                 return WITH_STRATEGY;
>             }
>             @Override
>             public void accept(final Traversal.Admin<?, ?> traversal, final String key) {
>                 try {
>                     String strategyName = classMap.get(String.valueOf(traversal.getSideEffects().getSupplier(key).get()));
>                     if (strategyName != null) {
>                         ((TraversalStrategy) Class.forName(strategyName).newInstance()).apply(traversal);
>                     }
>                 } catch (Exception e) {
>                     return;
>                 }
>             }
>             private final Map<String, String> classMap = new LinkedHashMap<>();
>         };
>         private static final String WITH_STRATEGY = gdbSpecificSideEffect("withStrategies");
>         @Override
>         public abstract void accept(final Traversal.Admin<?, ?> traversal, final String key);
>         public abstract String getAccessor();
>         public abstract Optimizer instance();
>         private static String gdbSpecificSideEffect(final String key) {
>             return "GDB#" + key;
>         }
>     }
> }  
> {code}
> In the above example,  when people determine to use different provider related strategy, it could by easily merge into WithSideEffectOptimizerStrategy. Of course the above code is just a demo,  we may have many different kinds of Optimizer here。
> If we add this feature, so withSideEffect may take effect in two stages:
>  # when a certain traversal step executing, default case.
>  # when withSideEffect step are parsing, different graph provider may implement different logic here.
>  All kinds of opinions are welcomed !



--
This message was sent by Atlassian Jira
(v8.3.4#803005)