Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt plugins to new Plugin API introduced by #3210 #3813

Closed
40 of 43 tasks
jsvd opened this issue Aug 28, 2015 · 19 comments
Closed
40 of 43 tasks

Adapt plugins to new Plugin API introduced by #3210 #3813

jsvd opened this issue Aug 28, 2015 · 19 comments

Comments

@jsvd
Copy link
Member

jsvd commented Aug 28, 2015

Issue #3210 and PR #3812 #3895 change the Plugin API to:

  1. add stop (public), stop? (public) to LogStash::Inputs::Base
  2. rename teardown to close
  3. remove shutdown, finished. finished?, running?, terminating? from LogStash::Plugin

Refactor work needed on the plugins

Input plugins

Input plugins are now shutdown by an external call to plugin.stop instead of catching LogStash::ShutdownSignal exception.
Unless overridden, stop will simply makes stop? return true, thus allowing run to poll this and return after seeing the change.

In some plugins extra work must be done in stop to instruct run that it's time to return. For example, in the logstash-input-udp it's necessary to call @socket.close to make the blocking read on the socket raise an exception, thus breaking out the loop.
So, different input plugins will require different stop strategies.

Refactoring an input plugin involves:

  • removing rescue of ShutdownSignal exception
  • understand the nature of the run loop: is it a while? a consumer.subscribe {|event| }? is there a blocking operation on a socket/fd?
  • use stop? and/or override stop to make run return
  • put any other cleanup/bookkeeping tasks in close (currently done in teardown)
  • remove any calls to shutdown, finished, finished?, running? or terminating?

Then for testing you can use the shared example provided in elastic/logstash-devutils#32 in the following manner:

describe LogStash::Inputs::Http do
  let(:port) { rand(5000) + 1025 }
  it_behaves_like "an interruptible input plugin" do
    let(:config) { { "port" => port } }
  end
end
Testing the refactor
  1. clone logstash, switch to PR 3895
  2. clone logstash-devutils, switch to PR 32
  3. clone plugin repository, switch to refactor PR (check above)
  4. edit Gemfile to look like:
source 'https://rubygems.org'
gemspec
gem "logstash-core", :path => "/path/to/git/project/logstash"
gem "logstash-devutils", :path => "/path/to/git/project/logstash-devutils"
  1. run bundle install
  2. run bundle exec rspec

Filters and Outputs

Both will still shutdown using the ShutdownEvent sent by the pipeline so no major changes necessary.
The work in these plugins is:

  • to remove calls that are no longer in the pipeline <-> plugin contract: shutdown, finished, finished?, running? or terminating?
  • rename teardown to close

Work To Do

1. Input plugins

1.1 Default Input Plugins
1. Remove shutdown

Nothing to do.

2. Remove finished
3. Remove finished?

Nothing to do.

4. Remove running?

Nothing to do.

5. Remove terminating?

Nothing to do.

6. Rename teardown to close

Issue #3952 tracks this

7. Other tasks

@ph
Copy link
Contributor

ph commented Aug 28, 2015

Awesome @jsvd!

@suyograo
Copy link
Contributor

@jsvd thanks for the detailed analysis! I added 2 more points at the end

@jsvd
Copy link
Member Author

jsvd commented Aug 31, 2015

For all interested in testing this:

  1. clone logstash, switch to PR 3812 (now 3895)
  2. clone logstash-devutils, switch to PR 32
  3. clone plugin repository, switch to refactor PR (check above)
  4. edit Gemfile to look like:
source 'https://rubygems.org'
gemspec
gem "logstash-core", :path => "/path/to/git/project/logstash"
gem "logstash-devutils", :path => "/path/to/git/project/logstash-devutils"
  1. run bundle install
  2. run bundle exec rspec

@purbon
Copy link
Contributor

purbon commented Sep 1, 2015

@jsvd work on a few inputs here, waiting to get more feedback from you before moving forward with more. Open question for me here is how deep to go on the "cleanup" ? 😸

@colinsurprenant
Copy link
Contributor

before moving forward too deep (in particular for close/teardown and stop? we need to settle on #3810 and #3812 (now #3895)

@purbon we should avoid mixing cleanup & refactor work. one or the other but not both in the same PR, start with refactor since this is what is required here. after we can add/merge cleanups.

@colinsurprenant
Copy link
Contributor

please note that some input plugins might need special handling/testing for when in blocked IO state to see if they can be unblocked from the pipeline thread form the stop method.

@jsvd
Copy link
Member Author

jsvd commented Sep 7, 2015

@colinsurprenant indeed. the one exception I'm not worried about is the logstash-input-stdin, since it's equally non interruptible with both the new and old apis. Even with the PR you created to use the java interopt to extract the channel and make it interruptible, it's a non breaking change so it doesn't need to be rushed, IMO.

@colinsurprenant
Copy link
Contributor

@jsvd +1

@wiibaa
Copy link
Contributor

wiibaa commented Sep 11, 2015

@colinsurprenant sorry to bump in, but as you are planning this huge refactoring, could you consider adding the small refactor described in #2447 about abstracting into base how to send an event to the filterworker(s) instead of exposing the queue in the run method. IMHO this could be the baseline for future enhancement on how inputs would be submitting events to the pipeline and allow to centralize ideas about detection/handling of back-pressure, batching of event, prioritization, dispatching, queue persistence etc etc. Thanks for reading!

@colinsurprenant
Copy link
Contributor

@wiibaa thanks for the heads up - I will followup on #2447.

@colinsurprenant
Copy link
Contributor

@jsvd @ph @jordansissel could use a review(s) of jordansissel/ruby-stud#27 to move forward with all plugins using Stud.interval

@andrewvc
Copy link
Contributor

Is there a reason that 'stop' and 'close' have different names? I think this will be very confusing to future plugin authors. It's already confusing to me now. Ideally they would both also make stop? work correctly (some outputs sleep).

@talevy
Copy link
Contributor

talevy commented Sep 17, 2015

@andrewvc

I think teardown(close) was originally intended for cleaning up, not instructing a plugin to effectively "stop" execution. one can be viewed as an "instruction" given to a running plugin. while close is an "instruction" given on a plugin that has been "stopped" (but might actually be running in the background via threads and open file handles).

I think it would be ok to rename stop to close for inputs. The only gotcha is that inputs that wish to override this and implement extra teardown actions will have to remember to call super. To avoid this, we can have the pipeline call another function that is not a part of the public api that will run the @stop_called.make_true stuff.

what do you think?

@andrewvc
Copy link
Contributor

@talevy I'm not clear on why they need to call super? Presuming that they don't ever check stop? what would the issue be?

@talevy
Copy link
Contributor

talevy commented Sep 17, 2015

I don't like the fact that people who wish to use #stop as a place to teardown have to know about the guts of state management around @stop_called. It is true, if stop? is never used, this is a non-issue. I just don't think it is very nice to have to know whether this is a non-issue or an issue.

@andrewvc
Copy link
Contributor

@talevy I misread your original comment. I do think we should have another function called externally that makes stop? return true. I think we should have a __step_stop? or the like function that does this that no one ever overrides.

@talevy
Copy link
Contributor

talevy commented Sep 17, 2015

disagree on the naming :) but yeah, that is what I meant!

@andrewvc
Copy link
Contributor

@talevy I meant __set_stop(true).

ph added a commit to logstash-plugins/logstash-output-s3 that referenced this issue Sep 21, 2015
ph added a commit to logstash-plugins/logstash-output-redmine that referenced this issue Sep 21, 2015
@jsvd
Copy link
Member Author

jsvd commented Oct 12, 2015

all default plugins now have been refactored to address the new api.
tracking non-default plugins in #3963

@jsvd jsvd closed this as completed Oct 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants