aspnet / WebHooks

[Archived] Libraries to create and consume web hooks on ASP.NET Core. Project moved to https://github.com/aspnet/AspLabs
Apache License 2.0
627 stars 439 forks source link

Remove webhook after retries #90

Closed adrianm64 closed 6 years ago

adrianm64 commented 7 years ago

Maybe I'm missing something obvious here but I can't find out how to remove webhooks once they have timed out or are gone.

Tried to implement an IWebHookSender but the methods in IWebHookStore all require a user argument to remove a webhook. The user is not available in the workitem.

I can pause or remove all filters from the in-memory webhook but they will come back once the store is refreshed.

private sealed class MyWebHookSender : DataflowWebHookSender
{
    private readonly IWebHookStore _webHookStore;

    public MyWebHookSender(ILogger logger, IWebHookStore webHookStore, IEnumerable<TimeSpan> retryDelays, ExecutionDataflowBlockOptions options)
        : base(logger, retryDelays, options) {
        _webHookStore = webHookStore;
    }

    protected override Task OnWebHookGone(WebHookWorkItem workItem) {
        await _webHookStore.DeleteWebHookAsync(** how to find user **, workItem.WebHook);
    }
}
HenrikFrystykNielsen commented 7 years ago

It's as little tricky - I agree. You can find the offending WebHook using the IWebHookStore.QueryWebHooksAcrossAllUsersAsync where you pass "*" as the action (or you get the specific action from the first NotificationDictionary from the WebHookWorkItem) and then the check the WebHook ID in the predicate. Once you have that, you can delete it.

adrianm64 commented 7 years ago

Thanks, I missed that the predicate included the user.

For anyone else needing it, here is my code

internal sealed class WebHookSender : DataflowWebHookSender
{
    private readonly IWebHookStore _store;

    public WebHookSender(ILogger logger, IWebHookStore store)
        : base(logger) {
        _store = store;
    }

    public WebHookSender(ILogger logger, IWebHookStore store, IEnumerable<TimeSpan> retryDelays, ExecutionDataflowBlockOptions options)
        : base(logger, retryDelays, options) {
        _store = store;
    }

    protected override Task OnWebHookFailure(WebHookWorkItem workItem) {
        return DeleteWebHook(workItem.WebHook.Id);
    }

    protected override Task OnWebHookGone(WebHookWorkItem workItem) {
        return DeleteWebHook(workItem.WebHook.Id);
    }

    private async Task DeleteWebHook(string webHookId) {
        string webHookUser = null;

        await _store.QueryWebHooksAcrossAllUsersAsync(new[] { "*" },
                                                      (webHook, user) => {
                                                           if (webHook.Id == webHookId) {
                                                               webHookUser = user;
                                                           }

                                                           return false;
                                                       });
        // Multiple workitems can run in parallel so not finding it in the store is not an error
        if (webHookUser != null) {
            await _store.DeleteWebHookAsync(webHookUser, webHookId);
        }
    }
}
dougbu commented 6 years ago

Thank you for your feedback. We're closing this issue as the questions asked here have been answered.