resolve icon indicating copy to clipboard operation
resolve copied to clipboard

Custom-read-model-connector projection handlers are not called in a new application

Open mgentry612 opened this issue 1 year ago • 0 comments

Describe the bug When creating a new application with the npx create-resolve-app command, custom-read-model-connector projection handlers are never called. This occurs with and without a template. It occurs with a custom-read-model-connector I built, and one that is present in the hacker-news example.

To Reproduce

  1. Create a new application with the hacker-news templatenpx create-resolve-app hacker-news-custom-read-model-connector -e hacker-news -t
  2. In common/read-models/search.projection.ts, add a console.log('STORY_CREATED event received in search.projection.ts') statement to the STORY_CREATED projection handler.
  3. npm run dev
  4. A window should be opened in your browser with the hacker-news app running. Click "login" and create a new account.
  5. Click "submit" and create a new story.
  6. Note that the console.log statement you created above in step 2 never printed.

Expected behavior Following the steps above, step 6 prints the console.log statement in the search projection handler STORY_CREATED

Desktop (please complete the following information):

  • OS: iOS
  • Browser: Chrome but it is replicable in Postman too
  • Node.js Version: 16.13.2
  • ReSolve Version: 0.34.3

Additional context I did quite a bit of debugging in the source code and the ending issue seems to be in runtime-base/lib/custom-read-model.js. The build function is called multiple times for the Search event subscriber. The first time, the events are retrieved from eventstoreAdapter.loadEvents as null and status.busy is set to false as expected. Then, however, the busy function is rerun and the eventstoreAdapter.loadEvents call returns events as an empty array, []. This results in returning an object where continue: false without updating status.busy to false.. When continue equals false, the execution reaches an empty if block with the comment, TODO: ??? in node_modules/@resolve-js/runtime-base/lib/notification-next.js.

This results in any subsequent real event, like STORY_CREATED, to be unhandled because the build function returns early because status.busy is true on line ~66: if (status == null || status.status !== 'deliver' || !!status.busy).

When the event array is returned empty, as described above, I can update the subscribers database to set busy to false and this seems to fix the issue, but I don't know what side effects this has and I don't know if it's addressing the underlying issue that an empty array of events is returned. I think the issue is one of two things: the build function should have never been called when there were no new events, or the busy status was never updated in the case when events.length is 0. If the latter is the case, the bottom code change seems to fix the immediate issue around line 130:

      } else if (events.length === 0) {
        // start potential bug fix
        await eventstoreAdapter.ensureEventSubscriber({
          applicationName,
          eventSubscriber,
          status: { ...status,
            busy: false
          },
          updateOnly: true
        });
        // end potential bug fix

        return {
          type: 'build-direct-invoke',
          payload: {
            continue: false
          }
        };
      } else if (events.length > 0) {

mgentry612 avatar May 09 '23 16:05 mgentry612