All Apps and Add-ons

sideview pulldown having downstream effect bis

guilhem
Contributor

Hello there,

I am having the exact same problem as this one(pulldown refresh after search), but I cannot use the solution given here (can't put the search upstream for several reasons).

Also the search dispatched upstream was different each time, so the "fix" done in 2.2.7 doesn't apply here.

I've managed to solved partly the problem using a little custom behavior (posted in the link above)

BUT, it seems that the search is still dispatched, as the pulldown is not emptied and repopulated, but we can see the progress bar at the top of it, like if the search was run again. I would like to prevent this to happen.

Is there a handy way to achieve this using custom behavior (or by another way maybe)?

Thanks!

Guilhem

guilhem
Contributor

Allright, after reading the DOCs again, and the detailed answer you wrote, I was able to put something together, which works very partially.

So I have wrote this CustomBehavior module (the comments are not mine, I have just copy-pasted them):

Sideview.utils.declareCustomBehavior("refreshOnlyOnce", function(pulldownModule) {

var requiresDispatchReference = pulldownModule.requiresDispatch.bind(pulldownModule);

/**
 * if the module is configured dynamically then we have to trigger 
 * a new dispatched search. Note that we actually defer to 
 * DispatchingModule to calculate it.
 */
pulldownModule.requiresDispatch = function() {
    var result;
    if (this.contextRefreshOnlyOnce != null)
    {
            result = false;
    }
    else
    {
            result = requiresDispatchReference();
            this.contextRefreshOnlyOnce = this.getContext();
    }
    return result;
}

/**
 * called when a module from downstream requests new context data
 */
pulldownModule.getModifiedContext = function() {
    if (this.contextRefreshOnlyOnce !=null)
    {
            context = this.contextRefreshOnlyOnce;
    }
    else
    {
            context = this.getContext();
    }
    return context;
}

});

You need of course a contextRefreshOnlyOnce variable inside the application.js.

The search is dispatched the first time, and never after, but the problem is, as one can expect, the downstream values are always the one that has been set on page load, which means that any modification from upstream will not affect downstream of this module.

Additionaly, context values coming from static upstream pulldowns exists after this module, but for some reason "dynamic" context values (coming from resultsValueSetters after a search for example) does not.

I am still investigating on how to be able to refresh those values whithout the need to set the requiresDispatch to true again.

Guilhem


EDIT

Here is another attempt following your comment:

// Variable that will contain the search we have saved
var searchRefreshOnlyOnce = null;

Sideview.utils.declareCustomBehavior("refreshOnlyOnce", function(pulldownModule) {

// Save the default behavior of the pulldown module requiresDispatch function, so
// we can use it the first time (at page load)
var requiresDispatchReference = pulldownModule.requiresDispatch.bind(pulldownModule);

/**
 * if the module is configured dynamically then we have to trigger 
 * a new dispatched search. 
 * if the search context is not null, we do not require to dispatch, as we will
 * use the previously saved search.
 */
pulldownModule.requiresDispatch = function() {
    var result;

    // if this is not the first the requiresDispatch function is called
    if (this.searchRefreshOnlyOnce != null)
    {
            result = false;
    }
    // Default behavior when called the first time (we savez the search param for later
    else
    {
            result = requiresDispatchReference();
            this.searchRefreshOnlyOnce = this.getContext().get("search");
    }
    return result;
}

/**
 * called when a module from downstream requests new context data
 */
pulldownModule.getModifiedContext = function() {
    var context = this.getContext();

    // If we have saved a search, let's retrieve it from instead of
    // using the new one (because the new one have no impact on what should be displayed
    // by this dynamic pulldown)
    if (this.searchRefreshOnlyOnce !=null)
    {
            context.set("search", this.searchRefreshOnlyOnce);
    }
    return context;
}

});

But this doesn't work. I mean yes the search and upstream params are set correctly, but the loading bar and the search are run again.

After a little exploration I think it is due to the getContext() method that recursively calls all the parents to update, and those that requiresDispatch will then trigger the search to be run again (it's just a guess after looking at the function).

(See AbstractModule.js getContext() function)

I am beginning to think it may not be possible to achieve what I want, but at least I have learned something.


EDIT 2

corrected some typos and added comments.

sideview
SplunkTrust
SplunkTrust

Oh. Well there's another big gap here that I apologize for not noticing. Pulldown has a base getModifiedContext(), and that's how it outputs it's selected value for downstream modules. So you have to preserve that existing method as a reference, much like you did with requiresDispatch. This is really very advanced stuff and I should probably find some time to tinker with it and try to write a definitive answer.

0 Karma

guilhem
Contributor

Thansk for your comment, I have corrected the typos (I was performing test and copy-pasted without checking what I have pasted)

I will look again into this when I have some time.

0 Karma

sideview
SplunkTrust
SplunkTrust

Note that in the code you posted the methods of your CustomBehavior are actually commented out. You have a multiline comment (/*), which is never closed, so all code past that point is commented out. Most likely this also triggered a JS syntax error which may have caused other breakages. Can you fix that and post back?

Also change that htmlModule variable to "pulldownModule". I think that was a copy-paste from some HTML module's custombehavior example.

The answer to your concerns regarding other modules returning requiresDispatch, is too complex to write here. Yes and no.

0 Karma

guilhem
Contributor

Thanks for the tips, I have edited my answer accordingly, but there is still an (unsolvable?) problem due to the getContext() function I think.

sideview
SplunkTrust
SplunkTrust

Well, it will work. But the "search" is only one key inside the Context, so as you've discovered, this solution as written effectively prevents all upstream changes entirely. Instead you can keep just the Search object that is returned from context.get("search"), and then in getModifiedContext, make sure to return the rest of the normal context just fine, but only changing the "search" part, by doing context.set("search",this.secretSearch) before returning the context. Nice work, you've nearly gotten it. However I advise very aggressive testing because you're deep under the hood.

sideview
SplunkTrust
SplunkTrust

The problem is that whether the Pulldown chooses to reload it's options or not, doesn't affect whether that search gets dispatched or redispatched.

But let me back up a little. In learning how the system works, in a way there's a whole first set of hurdles that ends when you finally understand the meaning of "upstream" and "downstream", and what a "push" is. After that many things become suddenly clear and in fact you may start annoying your coworkers with your easy answers to formerly opaque questions.

But there is a second set of hurdles that concerns this business of why searches get dispatched, where they get dispatched, when they get dispatched, etc...

Both of these areas are explained pretty fully in a Sideview Utils docs page, within the Sideview Utils app itself, at "Key Techniques > Overview of the Advanced XML". Or from the homepage you can click the link that says "on to the examples!" (the link lies a little). Note that you may need to upgrade to the latest Sideview Utils to see these docs. If you have the old 1.3.5 from Splunkbase they wont be there. Upgrade to latest (2.2.10) by getting it from the Sideview website http://sideviewapps.com/apps/sideview-utils.

The bad news is that the page is a little long and the concepts may require slower reading than you might like.

Nonetheless, if you read that page carefully, and then think back to your XML, you'll see it's the framework itself that dispatches the search for that Pulldown module.

Generally, there can be ways in which from a customBehavior you can alter the underlying framework behavior. In this particular case though, it's such a core thing in the framework that you should think of it as an impossible task. Superficially you might discover the "requiresDispatch" method and think you can override that, but this will only cause a cascade of other unacceptable problems and in short that whole approach will not work so don't go there.

Whst you really need, in plain English, is a CustomBehavior module downstream from the Search and upstream from the Pulldown, whose customBehavior implementation triggers the dispatch the first time, grabs the search object with it's dispatched job, and explicitly saves that search object for later. then all subsequent times a new push data comes down through, that CustomBehavior module would have to return false from requiresDispatch, and then from getModifiedContext, it would have to return a context with the search object it squirrelled away beforehand. Unfortunately putting this together and testing it is more time than I have right now. I will try to update my answer later.

However I'm considering a number of other broad additions to Sideview Utils, some of which would give you the leeway to address this use case, although in a completely different way. If those other approaches bear fruit here I'll come back and update my answer with that as well.

guilhem
Contributor

Hello Nick and thanks for your detailed answer.

I was thiking there might be an underlying problem with the approach of modifying the pulldown module with a custom behavior, as it is not responsible for the search dispatch, so the modification/ interseption has to be done upstream.

I will try to put this together (and read again the advanced XML doc), and hopefully I may post here the results.

Thanks,

Guilhem

Get Updates on the Splunk Community!

Introducing the 2024 Splunk MVPs!

We are excited to announce the 2024 cohort of the Splunk MVP program. Splunk MVPs are passionate members of ...

Splunk Custom Visualizations App End of Life

The Splunk Custom Visualizations apps End of Life for SimpleXML will reach end of support on Dec 21, 2024, ...

Introducing Splunk Enterprise 9.2

WATCH HERE! Watch this Tech Talk to learn about the latest features and enhancements shipped in the new Splunk ...