onyx

FYI: alternative Onyx :onyx: chat is at <https://gitter.im/onyx-platform/onyx> ; log can be found at <https://clojurians-log.clojureverse.org/onyx/index.html>
eriktjacobsen 2018-03-23T23:12:04.000105Z

We are trying to diagnose a difficult to reproduce error and this is a shot in the dark: Are there any guarantees around a trigger with a threshold of a single segment and create/apply aggregations for that window? Our apply fn clears out a specific key in the state and based on logic might re-populate that key. Our emit fn for trigger runs side-effects based on the contents of that key. We might be seeing multiple emits, which could be explained by the emit fn being called for a segment before that segment's associated apply was finished executing.

eriktjacobsen 2018-03-23T23:12:57.000196Z

This is all in a single peer / virtual peer env.

lucasbradstreet 2018-03-23T23:15:36.000263Z

@eriktjacobsen the task lifecycle is batched, so you can see the create/apply be performed for a given window more than once in a single batch, during which time it’ll collect the segments to emit downstream

eriktjacobsen 2018-03-23T23:15:41.000196Z

Example: the apply does this: (dissoc state :txts-to-send)(if logic (assoc state :txts-to-send phone-numbers) state) and the trigger is set to {:trigger/on :onyx.triggers/segment :trigger/threshold [1 :elements]}. Could we see trigger emit fn executed multiple times with duplicate state(without the apply having been run to clear out the key)?

lucasbradstreet 2018-03-23T23:17:05.000081Z

The apply should always have cleared out the key after each segment.

lucasbradstreet 2018-03-23T23:19:31.000151Z

Sorry, what I just said is not true.

lucasbradstreet 2018-03-23T23:19:57.000007Z

It will create / apply, then call emit-fn and collect the segment to be emitted, repeating that process for each segment in the batch

lucasbradstreet 2018-03-23T23:20:18.000048Z

then it will collect all of the emitted segments and send them to the next task / plugin output as a batch

lucasbradstreet 2018-03-23T23:21:00.000004Z

The emit will have access to the exact state after the apply on each emit, so I believe it should all work how you want.

lucasbradstreet 2018-03-23T23:21:11.000276Z

are you using refinements, or eviction?

lucasbradstreet 2018-03-23T23:24:20.000161Z

The typical approach you would use is a create to build the state transition, apply to apply that entry to the state, then a refinement to get rid of any state that you don’t want after the trigger fires.

eriktjacobsen 2018-03-23T23:24:36.000179Z

no, we are on 0.12.0 and trigger is

:windows [{:window/id :notifications-handler
                     :window/task task-name
                     :window/type :global
                     :window/aggregation ::notification-handler-update-aggregation}]
          :triggers [{:trigger/window-id :notifications-handler
                      :trigger/id :notifications-handler0
                      :trigger/emit ::emit-notifications
                      :trigger/on :onyx.triggers/segment
                      :trigger/threshold [1 :elements]}]}

lucasbradstreet 2018-03-23T23:26:04.000268Z

Could you define the specific create and apply that you’re using?

lucasbradstreet 2018-03-23T23:26:16.000172Z

It’s a bit fuzzy with the dissoc and if logic there

eriktjacobsen 2018-03-23T23:26:27.000184Z

Alright. We can switch to that approach. This code started on 0.10 Also, this is still a shot in the dark as to whether the trigger firing multiple times without the apply clearing could be the cause. Just was curious if that was a known possibility

eriktjacobsen 2018-03-23T23:26:43.000140Z

(defn create-notifications-state-update
  [window segment]
  (if (:component-configs segment)
    segment
    (when (:component-changes segment)
      segment)))

(defn apply-notifications-state-update
  [window state update-message]
  (let [state (dissoc state :notifications-to-send)]
    (if-let [configs (:component-configs update-message)]
      (initialize-state-config-map state configs)
      (if (:component-changes update-message)
        (handle-notifications-for-changes state update-message)
        state))))

lucasbradstreet 2018-03-23T23:27:22.000218Z

ok, right, so the emit-fn will be passed the state after apply updates it

lucasbradstreet 2018-03-23T23:28:25.000230Z

then if you need to clear out any state after the emit, a refinement is the way to go. I think you’re essentially doing that up front in the apply though.

eriktjacobsen 2018-03-23T23:28:37.000009Z

handle-notifications-for-changes would populate the :notifications-to-send key.... yeah 99% of the time it seems 1apply-1emit seems to hold and we don't get duplicates. It's still possible this is in our business logic, just trying to check onyx trigger-behavior off the list.

lucasbradstreet 2018-03-23T23:28:42.000120Z

You shouldn’t see a trigger firing multiple times without an apply being called in between

👍 1
lucasbradstreet 2018-03-23T23:28:58.000083Z

K, let me know how you end up

eriktjacobsen 2018-03-23T23:29:36.000048Z

Thanks for your quick help

lucasbradstreet 2018-03-23T23:29:49.000086Z

No worries