<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Why doesn't this custom search command call class method? in Splunk Dev</title>
    <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239436#M3047</link>
    <description>&lt;P&gt;Yes, that's the code.&lt;/P&gt;</description>
    <pubDate>Sat, 26 Nov 2016 21:05:43 GMT</pubDate>
    <dc:creator>plucas_splunk</dc:creator>
    <dc:date>2016-11-26T21:05:43Z</dc:date>
    <item>
      <title>Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239429#M3040</link>
      <description>&lt;P&gt;Given an excerpt from custom search command:&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;logger = logging.getLogger( 'nbclosest' )
logger.setLevel( logging.DEBUG )

K_STAG  = 'stop_tag'
K_TIME  = '_time'
K_VDIST = 'vehicle_distance'
K_VID   = 'vehicle_id'

@Configuration()
class NextBusClosestStop( EventingCommand ):
    class ConfigurationSettings( EventingCommand.ConfigurationSettings ):
        required_fields = ConfigurationSetting(value=[K_TIME, K_VID, K_VDIST, K_STAG])

    def __init__( self ):
        super( NextBusClosestStop, self ).__init__()
        # ...

    def drain( self ):
        logger.debug( 'enter drain()' )
        # do drain code

    def transform( self, records ):
        logger.debug( 'enter transform()' )
        for rec in records:
            # ...
            yield rec

        logger.debug( 'exit transform()' )
        self.drain()
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;The &lt;CODE&gt;transform()&lt;/CODE&gt; function is called and both &lt;CODE&gt;enter transform()&lt;/CODE&gt; and &lt;CODE&gt;exit transform()&lt;/CODE&gt; are in &lt;CODE&gt;search.log&lt;/CODE&gt;, but I never see &lt;CODE&gt;enter drain()&lt;/CODE&gt; logged --- and the code is indeed never called (because the results produced are wrong).&lt;/P&gt;

&lt;P&gt;However, if I copy &amp;amp; paste the code from &lt;CODE&gt;drain()&lt;/CODE&gt; and put it "inline" in place of &lt;CODE&gt;self.drain()&lt;/CODE&gt;, then the code executes.&lt;/P&gt;

&lt;P&gt;How can it be the case that &lt;CODE&gt;self.drain()&lt;/CODE&gt; isn't called?&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 17:09:27 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239429#M3040</guid>
      <dc:creator>plucas_splunk</dc:creator>
      <dc:date>2016-11-26T17:09:27Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239430#M3041</link>
      <description>&lt;P&gt;looks like self.drain() is called from within self.transform()?&lt;/P&gt;

&lt;P&gt;I see you yield results in a for loop too.  Doesn't that cause the transform function to yield and exit when records exist?&lt;/P&gt;

&lt;P&gt;I think you can fix by calling self.drain() after you use "for x in self.transform():" instead of wrapping it up inside of self.transform()&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 18:33:01 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239430#M3041</guid>
      <dc:creator>jkat54</dc:creator>
      <dc:date>2016-11-26T18:33:01Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239431#M3042</link>
      <description>&lt;BLOCKQUOTE&gt;
&lt;P&gt;looks like self.drain() is called from within self.transform()?&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;

&lt;P&gt;Yes.&lt;/P&gt;

&lt;BLOCKQUOTE&gt;
&lt;P&gt;I see you yield results in a for loop too.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;

&lt;P&gt;Yes, as does every example I've ever seen.&lt;/P&gt;

&lt;BLOCKQUOTE&gt;
&lt;P&gt;Doesn't that cause the transform function to yield and exit when records exist?&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;

&lt;P&gt;AFAIK, &lt;CODE&gt;transform()&lt;/CODE&gt; is called with multiple records that Splunk sends in "chunks" (which is why this is called a "Chunked External Processor" in version 2 of the Python SDK). The &lt;CODE&gt;transform()&lt;/CODE&gt; function then iterates over the records doing something with them. For those it wishes to return to Splunk, it calls &lt;CODE&gt;yield&lt;/CODE&gt;. However, despite its name, I doubt &lt;CODE&gt;yield&lt;/CODE&gt; actually yields control because then --- somehow --- the &lt;CODE&gt;for&lt;/CODE&gt; loop would have to pick up from where it left off the next time &lt;CODE&gt;transform()&lt;/CODE&gt; is called. Hence, I believe &lt;CODE&gt;yield&lt;/CODE&gt; is probably closer to "print."&lt;/P&gt;

&lt;BLOCKQUOTE&gt;
&lt;P&gt;I think you can fix by calling self.drain() after you use "for x in self.transform():" instead of wrapping it up inside of self.transform()&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;

&lt;P&gt;But the way the API works is that &lt;CODE&gt;transform()&lt;/CODE&gt; is called by Splunk --- you do &lt;EM&gt;not&lt;/EM&gt; call it yourself.&lt;/P&gt;

&lt;P&gt;And this doesn't explain why "inline" code would be executed while the call to the function would not.&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 18:57:17 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239431#M3042</guid>
      <dc:creator>plucas_splunk</dc:creator>
      <dc:date>2016-11-26T18:57:17Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239432#M3043</link>
      <description>&lt;P&gt;&lt;A href="http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do"&gt;http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do&lt;/A&gt;&lt;/P&gt;

&lt;P&gt;I'm not sure what you mean by inline but my statement still holds some water.  Yield returns a generator object and Python will iterate through the function until it hits the yield.  As long as there is a records array to be had, you'll never see self.drain called.  When you call self.transform without a records array self.drain will happen because the "for rec in records:" doesn't execute and this the yield doesn't take place.&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 19:28:41 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239432#M3043</guid>
      <dc:creator>jkat54</dc:creator>
      <dc:date>2016-11-26T19:28:41Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239433#M3044</link>
      <description>&lt;P&gt;I went for help and had it carefully pointed out to me that the exit transfor log happens even though it's outside of the loop too.  This is very interesting indeed.&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 20:09:41 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239433#M3044</guid>
      <dc:creator>jkat54</dc:creator>
      <dc:date>2016-11-26T20:09:41Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239434#M3045</link>
      <description>&lt;P&gt;Can you share your code or is this it?&lt;/P&gt;

&lt;P&gt;&lt;A href="https://github.com/paul-j-lucas/nextbus-util/blob/master/splunk/etc/apps/search/bin/nbclosest.py"&gt;https://github.com/paul-j-lucas/nextbus-util/blob/master/splunk/etc/apps/search/bin/nbclosest.py&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 20:46:56 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239434#M3045</guid>
      <dc:creator>jkat54</dc:creator>
      <dc:date>2016-11-26T20:46:56Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239435#M3046</link>
      <description>&lt;P&gt;Yes, that's the part that is most confusing.&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 21:05:32 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239435#M3046</guid>
      <dc:creator>plucas_splunk</dc:creator>
      <dc:date>2016-11-26T21:05:32Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239436#M3047</link>
      <description>&lt;P&gt;Yes, that's the code.&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 21:05:43 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239436#M3047</guid>
      <dc:creator>plucas_splunk</dc:creator>
      <dc:date>2016-11-26T21:05:43Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239437#M3048</link>
      <description>&lt;P&gt;By "inline" I mean that instead of calling &lt;CODE&gt;drain()&lt;/CODE&gt;, I copy the code &lt;EM&gt;from&lt;/EM&gt; &lt;CODE&gt;drain()&lt;/CODE&gt; and paste a copy of it &lt;EM&gt;to&lt;/EM&gt; where I call &lt;CODE&gt;drain()&lt;/CODE&gt;.&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 21:15:30 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239437#M3048</guid>
      <dc:creator>plucas_splunk</dc:creator>
      <dc:date>2016-11-26T21:15:30Z</dc:date>
    </item>
    <item>
      <title>Re: Why doesn't this custom search command call class method?</title>
      <link>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239438#M3049</link>
      <description>&lt;P&gt;After doing some more reading on &lt;CODE&gt;yield&lt;/CODE&gt;, it turns out that putting &lt;CODE&gt;yield&lt;/CODE&gt; into a sub-function turns &lt;EM&gt;that&lt;/EM&gt; function into a generator and, in order to get results out of it, one has to iterate over &lt;EM&gt;that&lt;/EM&gt; generator:&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;    def drain( self ):
        recs = self.vdict.values()
        for rec in sorted( recs, key=operator.itemgetter( K_TIME ) ):
            yield rec
        self.vdict.clear()
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;Then to call it:&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;            for rec in self.drain():
                yield rec
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;In Python &amp;gt;= 3.3, one can instead do:&lt;/P&gt;

&lt;PRE&gt;&lt;CODE&gt;            yield from self.drain()
&lt;/CODE&gt;&lt;/PRE&gt;

&lt;P&gt;but Splunk currently ships with Python 2.7.11.&lt;/P&gt;</description>
      <pubDate>Sat, 26 Nov 2016 21:41:17 GMT</pubDate>
      <guid>https://community.splunk.com/t5/Splunk-Dev/Why-doesn-t-this-custom-search-command-call-class-method/m-p/239438#M3049</guid>
      <dc:creator>plucas_splunk</dc:creator>
      <dc:date>2016-11-26T21:41:17Z</dc:date>
    </item>
  </channel>
</rss>

