question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Only first hook triggers

See original GitHub issue

Description Seems like new hook system disallows to have multiple hooks attached to same event. Current implementation fires only first assigned hook.

To Reproduce Add two hooks for the same event. Fire the event. Only first one would actually triggered.

Expected behavior All defined hooks should trigger.

Details

  • Affected Component: Hooks Manager
  • Hypervisor: LXD
  • Version: 5.10.3

Seems like Hooks manager was implemented without such behavior in mind.

First of all, hook to trigger is got by get_hook

    # Returns a hook by key
    def get_hook(type, key)
        @hooks[type.downcase.to_sym][key]
    end

Ok, let’s find out what would we get here

        hook_pool.each do |hook|
            hook.extend(HEMHook)

            if !hook.valid?
                @logger.error("Error loading hooks. Invalid type: #{hook.type}")
                next
            end

            key = hook.key

            @hooks[hook.type][key] = hook
            @hooks_id[hook.id]     = hook
            @filters[hook.id]      = hook.filter(key)
        end

Simple, if key already exists, the value would be rewritten by latter iteration. So ok, maybe key is somewhat unique?

    # Generates a key for a given hook
    def key
        begin
            case type
            when :api
                self['TEMPLATE/CALL']
            when :state
                "#{self['TEMPLATE/RESOURCE']}/"\
                "#{self['TEMPLATE/STATE']}/"\
                "#{self['TEMPLATE/LCM_STATE']}"
            else
                ''
            end
        rescue StandardError
            ''
        end
    end

So, the packaged implementation of the hooks manager is simply broken.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
divanikuscommented, Mar 31, 2020

@kvaps @christian7007 Submitted the PR.

2reactions
divanikuscommented, Mar 31, 2020

Fix is kind of straightforward

--- onehem-server.rb    2020-03-30 22:53:12.759085714 +0000
+++ /usr/lib/one/onehem/onehem-server.rb        2020-03-30 22:32:08.000000000 +0000
@@ -276,7 +276,8 @@

             key = hook.key

-            @hooks[hook.type][key] = hook
+            @hooks[hook.type][key] = []          unless @hooks[hook.type].key?(key)
+            @hooks[hook.type][key].push(hook.id) unless @hooks[hook.type][key].include?(hook.id)
             @hooks_id[hook.id]     = hook
             @filters[hook.id]      = hook.filter(key)
         end
@@ -300,7 +301,8 @@
         key    = hook.key
         filter = hook.filter(key)

-        @hooks[hook.type][key] = hook
+        @hooks[hook.type][key] = []          unless @hooks[hook.type].key?(key)
+        @hooks[hook.type][key].push(hook_id) unless @hooks[hook.type][key].include?(hook_id)
         @hooks_id[hook_id] = hook
         @filters[hook_id]  = filter

@@ -312,7 +314,8 @@
     def delete(hook_id)
         hook = @hooks_id[hook_id]

-        @hooks[hook.type].delete(hook.key)
+        @hooks[hook.type][hook.key].delete(hook_id)
+        @hooks[hook.type].delete(hook.key) if @hooks[hook.type][hook.key].empty?
         @filters.delete(hook_id)
         @hooks_id.delete(hook_id)
     end
@@ -323,7 +326,7 @@
     end

     # Returns a hook by key
-    def get_hook(type, key)
+    def get_hooks(type, key)
         @hooks[type.downcase.to_sym][key]
     end

@@ -537,11 +540,14 @@
                 end

                 content   = Base64.decode64(content)
-                hook      = @hooks.get_hook(type, key)
+                hooks     = @hooks.get_hooks(type, key) || []

                 body = Nokogiri::XML(content)

-                @am.trigger_action(ACTIONS[0], 0, hook, body) unless hook.nil?
+                hooks.each do |hook_id|
+                    hook = @hooks.get_hook_by_id(hook_id)
+                    @am.trigger_action(ACTIONS[0], 0, hook, body) unless hook.nil?
+                end

                 reload_hooks(key, body) if UPDATE_CALLS.include? key
             when :RETRY
@@ -576,7 +582,7 @@
         params = hook.arguments(event)
         host   = hook.remote_host(event)

-        @logger.info("Executing hook for #{hook.key}")
+        @logger.info("Executing hook #{hook.id} for #{hook.key}")

         rc = nil

@@ -592,9 +598,9 @@
         end

         if rc.code.zero?
-            @logger.info("Hook successfully executed for #{hook.key}")
+            @logger.info("Hook #{hook.id} successfully executed for #{hook.key}")
         else
-            @logger.error("Failure executing hook for #{hook.key}")
+            @logger.error("Failure executing hook #{hook.id} for #{hook.key}")
         end

         xml_out = build_response_body(params, rc, host, hook.remote?, false)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Run useEffect Only Once - CSS-Tricks
Hooks make it possible to organize logic in components, making them tiny and reusable without writing a class. In a sense, they're React's...
Read more >
How to trigger useEffect in React only once AFTER some ...
I am trying to use useEffect hook in React to trigger some functions only once. I know that this could normally be done...
Read more >
React Hooks for the first time — simple as possible - Medium
There are some cases when we want to trigger a function when something was changed such as function reference, variable, state, or props....
Read more >
How the useEffect Hook Works (with Examples) - Dave Ceddia
The useEffect hook is the Swiss Army knife of all the hooks. It's the solution to many problems: how to fetch data when...
Read more >
Trigger pipelines by using the API - GitLab Docs
You can view and copy the full token for all triggers you have created. You can only see the first 4 characters for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found