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 08:55:00 UTC

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

Stark Arya created TINKERPOP-2299:
-------------------------------------

             Summary: 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


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() ):

 
{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}
// code placeholder
/*
 * (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}
 All kinds of opinions are welcomed !



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