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

Dynamic Enable/ Disable a function #578

Closed
rustd opened this issue Oct 6, 2015 · 11 comments
Closed

Dynamic Enable/ Disable a function #578

rustd opened this issue Oct 6, 2015 · 11 comments

Comments

@rustd
Copy link

rustd commented Oct 6, 2015

have an option in the dashboard to disable a function.
Implementation
We could write to Storage the list of active functions. When a user clicks disable in the dashboard, we update the storage settings and disable the listener for this function.

@rustd rustd added the Dashboard label Oct 6, 2015
@mathewc
Copy link
Member

mathewc commented Oct 6, 2015

More implementation notes: Settings for whether each function is currently enabled/disabled could live in Azure Storage. When a user clicks disable in the Dashboard, we update the flag in storage for that function, and at the same time the currently active listener for that function is also disabled in the running host so it will stop immediately. It won't start running again until enabled.

In addition to this Dashboard mechanism, I can also see it being useful for us to support an EnabledAttribute that could be applied to functions. The attribute would allow a app setting / value to be specified, so that on startup, the function will only run if that appsetting / value exists. Thus, jobs can be enabled/disabled by changing settings in the portal. The setting change will cause the Web App host to restart.

@iremmats
Copy link

Please implement this. :)

@mathewc
Copy link
Member

mathewc commented Oct 20, 2015

The proposal is to add a DisableAttribute that can be used to conditionally disable functions as follows:

  • Can be applied at the Parameter/Method/Class level
  • Only affects triggered functions
  • [Disable("setting")] - If a config/environment value exists for the specified setting name, and its value is "1" or "True" (case insensitive), the function will be disabled.
  • [Disable(typeof(DisableProvider))] - custom Type declaring a function of signature bool IsDisabled(MethodInfo method). We'll call this method to determine if the function should be disabled.
  • This is a startup time only check. For disabled triggered functions, we simply skip starting of the function listener. However, when you update app settings bound to these attributes, your WebJob will automaticallly restart and your settings will take effect.
  • Setting names can include binding parameters (e.g. {MethodName}, {MethodShortName}, %test%, etc.)

Does that meet your needs @iremmats @kamranayub?

@kamranayub
Copy link

This is a startup time only check.

So in a continuous job, let's say a queue processor, could I update a setting in Azure and it would disable it (or does changing a setting in Azure already auto-restart continuous webjobs?)?

That would need to work for this to be useful for continuous jobs. Right now I can check for the presence of an app setting myself when the function is triggered.

@mathewc
Copy link
Member

mathewc commented Oct 20, 2015

Yes - updating a setting causes a restart of your continuous WebJob. This is just behavior inherited for all Web Apps - when you update settings, your WebApp needs to be restarted for those updates to take effect.

So in this context, you have the ability to toggle individual jobs on/off depending on how you map the settings to attributes. Might be 1:1, 1:N, etc.

Checking for the setting yourself when the WebJob is triggered is very sub optimal - when I heard you were doing this as a workaround, I decided to implement this so you wouldn't have to do that :) With what you have now, you still have a listener that is continuously polling the queue, pulling messages off and starting the whole processing pipeline just to hit your code to ignore the message. With DisableAttribute, the listener won't even be running - no compute cycles wasted :)

@kamranayub
Copy link

Excellent, then this will totally meet my use cases! 👍

@iremmats
Copy link

I think this solves my uses cases too. Excellent work, really appreciate how easy it is to get in touch with you guys 👍

@mathewc
Copy link
Member

mathewc commented Oct 20, 2015

Resolved by f958e47. Also added a sample here.

@mathewc mathewc closed this as completed Oct 20, 2015
@phoxha
Copy link

phoxha commented Jul 21, 2016

Thank you for this.

When using [Disable("Disable_Queue")] I can't use an app setting or constant but need to do a DB look up (run a method) to see if queue is set to active by some outside process. How can I run a method here since this only uses a constant? Please give me a sample.

Does anyone have any examples on how to implement this:
[Disable(typeof(DisableProvider))] - custom Type declaring a function of signature bool IsDisabled(MethodInfo method).

Thanks
Pari

@kamranayub
Copy link

You may just need to do complex logic in the method. Exit if you don't want
it to run. I think you can reset the dequeue count to prevent dequeuing
when you exit.

On Thu, Jul 21, 2016, 09:25 phoxha notifications@github.com wrote:

Thank you for this.

When using [Disable("Disable_Queue")] I can't use an app setting or
constant but need to do a DB look up (run a method) to see if queue is set
to active by some outside process. How can I run a method here since this
only uses a constant? Please give me a sample.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#578 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAiaa6G3eezet0kneLfcqdOEDL56H50-ks5qX4FQgaJpZM4GKKnY
.

@phoxha
Copy link

phoxha commented Jul 21, 2016

Thanks. What do you mean by "reset the dequeue count".
I need to clarify that I am running this app locally in my server, not in the cloud.

It looks like [Disable(typeof(DisableProvider))] only fires on app start so it acts the same as using appsettings. I was hoping that it would allow me to stop AND restart the queue pump based on some dynamic value without having to restart the application. Am I wrong in saying that the solution provided does not really allow you you to stop and restart the queue pump. Once the queue has been disabled, you it cant really restart on its own based on some dynamic value, correct?

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

5 participants