[
https://issues.apache.org/jira/browse/TINKERPOP-2299?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16935823#comment-16935823
]
stephen mallette commented on TINKERPOP-2299:
---------------------------------------------
Well, the idea to this point was that providers would produce custom libraries
that users could depend on that included these sorts of things. JanusGraph and
DataStax Graph does such things for Geo types, for example. That said, I can
see that such an approach adds some burden to the provider, especially if it's
only a small handful of classes they are looking to expose (which I imagine is
your case).
I think the preferred approach then is for you to use `with()` which I think is
nicer for users anyway. Can you simply do:
{code}
g.with("GDB#withStrategies","DetachedElementStrategy").otherSteps()
{code}
or, even better imo (i'm assuming you're just trying to allow users to
configure the traversal to detach with properties):
{code}
g.with("GDB#includeProperties",true).otherSteps()
{code}
Is there some reason that approach doesn't work?
> 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 <[email protected]>
> * 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)