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

Add WebWorker Thread Support for Running Tasks #348

Merged
merged 17 commits into from
Feb 22, 2019
Merged

Conversation

pr1sm
Copy link
Collaborator

@pr1sm pr1sm commented Feb 21, 2019

Changes

  • Implement TaskThreadManager that spawns worker threads for each task
  • Implement runnerThread.js to handle passing events between TaskManager and TaskRunner using the WebWorker api
  • Add support to use TaskThreadManager in frontend by setting environment variable
    • set NEBULA_RUNNER_CONCURRENCY_TYPE to thread to enable this

Checks

  • CI passes
  • Coverage (<2%∆)
  • Manual Checks
    • Ensure Task Management remains functional when using TaskThreadManager
      • Tasks can be started (individually and in bulk)
      • Tasks can be stopped (individually and in bulk)
      • Tasks are stopped automatically when frontend closes
      • Proxies are sent over correctly
      • Captcha harvesting works correctly
      • Webhooks are sent properly
      • Delays are sent properly and change dynamically
      • Runs are logged properly
      • Any other task manager functionality I forgot 😅

fixes #192

Items left to complete All Items Complete

  • Graceful cleanup on close. Closing the frontend does send a message to close workers, but they do not respond done
  • Refactor out shared parts of runner<x>.js to reduce duplicate code done
  • Refactor out shared parts of Task<x>Manager to reduce duplicate code done
    • While writing the TaskThreadManager there was so much duplicate code from TaskProcessManager, the only significant changes I made were the functions I used to adhere to the webworker api. I want to refactor out this shared code so we don't have to change code in two places when dealing with bugs. done (see https://github.com/walmat/nebula/issues/192#issuecomment-466199341 for more details)

This commit implements a task manager variant that uses worker threads. A new worker is spawned for each new task that appears. All functionality should work, but hasn't been fully tested at this time.

The TaskThreadManager is added to the export list for use in the
frontend.
THis commit fixes some various spelling typos found in the process manager files when implementing the task thread manager.
This commit updates the frontend to support using the task thread manager. The dev environment is adjusted to use it, but more testing should occur before it is used as the default.

Further, a check was added to make sure worker threads are supported before using the TaskThreadManager. If the are not supported a warning message is printed and the TaskProcessManager is used instead.
@pr1sm pr1sm added type:enhancement New feature or request area:task-runner Related to Nebula's Task Runner package priority:urgent Issues that need to be solved right away labels Feb 21, 2019
@pr1sm pr1sm added this to the Beta 6 Release milestone Feb 21, 2019
@pr1sm pr1sm requested a review from walmat February 21, 2019 00:25
@pr1sm pr1sm changed the base branch from master to b1.0.0-beta.6 February 21, 2019 00:26
@pr1sm pr1sm self-assigned this Feb 21, 2019
Copy link
Owner

@walmat walmat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks beautiful man. Have you noticed any performance improvements regarding latency and CPU usage? Just curious if you’ve done any benchmarking yet!

Just a few questions, no changes. Well done.

packages/frontend/lib/task/adapter.js Outdated Show resolved Hide resolved
packages/frontend/lib/task/adapter.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 21, 2019

This looks beautiful man. Have you noticed any performance improvements regarding latency and CPU usage?

Not yet -- I did a test run of a single task and once I saw it "work", I opened the PR. By "work" I mean mostly work -- the status messages and captcha stuff worked, so I counted that as good enough for a WIP PR!

@walmat
Copy link
Owner

walmat commented Feb 21, 2019

This looks beautiful man. Have you noticed any performance improvements regarding latency and CPU usage?

Not yet -- I did a test run of a single task and once I saw it "work", I opened the PR. By "work" I mean mostly work -- the status messages and captcha stuff worked, so I counted that as good enough for a WIP PR!

Gotcha! So excited for this to hit beta 6 and for it to be rolled out. Good work 🙂

Copy link
Collaborator Author

@pr1sm pr1sm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass done. I'll tackle these changes as well as the planned refactors in the OP

packages/task-runner/src/shopify/runnerWorker.js Outdated Show resolved Hide resolved
packages/frontend/lib/task/adapter.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
packages/task-runner/src/shopify/taskThreadManager.js Outdated Show resolved Hide resolved
This commit addresses changes requested in PR:
- TaskManager now has an Abort event defined. this is used instead of a string literal
- TaskThreadManager now properly handles aborting on close
- TaskThreadManager has changes to remove eslint errors
- TaskThreadManager now checks for Webworker compatibliity in constructor. An error is thrown if there is no compatibility
- TaskThreadManager and TaskProcessManager are refactored slightly to reduce code duplication
- TaskManagerAdapter has better logic for falling back when worker threads are unavailable
This commit restructures manager files into their own folders. This helps visually group similar classes/files.
@pr1sm pr1sm added the status:on hold This issue is on hold due to another issue blocking it label Feb 21, 2019
This commit consolidates shared code between the two scripts that ran on child contexts (either process or thread). Most the the code has been extracted out to a base class and sub classes have been created for each implementation.
@walmat
Copy link
Owner

walmat commented Feb 21, 2019

Noticed a few bugs while playing around today. I'll do my best with the descriptions and repro steps.

Stack Trace while deregistering task events

Steps to reproduce

  1. Launch the frontend
  2. Close app by cmd + q (or windows equivalent)

Environments

Development && Production

Slack Trace

screen shot 2019-02-21 at 2 19 44 pm

No log messages

I've encountered this a few times and can't tell you why it happens. Sometimes I'll launch the app and the log messages will be there, and sometimes they won't show up and will only output in the console.

Steps to reproduce

  1. Launch the frontend
  2. Create any task
  3. Start task
  4. See if log section displays the output
  5. If it does, try to relaunch the app and repeat steps 1-4

Environments

Development && Production

Stack Trace

N/A

This commit refactors similar code from the TaskProcessManager and TaskThreadManager into a new SplitContextTaskManager. This class is used as a base class for all future task managers that run in split contexts. Subclasses for processes and worker threads have been implemented and are now used by the frontend.
@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 21, 2019

Thanks for testing this out!

I've just finished some major refactors to how the managers work, so I'm not sure if I've fixed the errors. I'll continue to do some more testing and see if I can get those to occur on my end.

Which OS were you testing on?

@walmat
Copy link
Owner

walmat commented Feb 21, 2019

No problem! I was testing on my Mac.

@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 21, 2019

I've been testing this out on Windows and I haven't seen either of those bugs. switching to macOS now. Are there any error messages that get printed to the console/logs when these errors occur? Both of these seem like they are related to the frontend side of things (in the launcher.js or adapter.js files), but I'm not sure...

@walmat
Copy link
Owner

walmat commented Feb 21, 2019

I've been testing this out on Windows and I haven't seen either of those bugs. switching to macOS now. Are there any error messages that get printed to the console/logs when these errors occur? Both of these seem like they are related to the frontend side of things (in the launcher.js or adapter.js files), but I'm not sure...

Interesting... yeah I don't see any errors or anything. Just doesn't log properly to the frontend for me. Could it be my version of electron or something? Idk..

@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 21, 2019

Yeah I always do a yarn install --force when testing out PRs to make sure I'm using the latest lock file. Another thing to ensure is that you've built the latest task-runner: yarn workspace @nebula/task-runner run build

@walmat
Copy link
Owner

walmat commented Feb 21, 2019

Yeah I always do a yarn install --force when testing out PRs to make sure I'm using the latest lock file. Another thing to ensure is that you've built the latest task-runner: yarn workspace @nebula/task-runner run build

hmm still seems to be happening to me. If it's only me, idc as much. Just wanna make sure it's not a production issue.

This commit fixes a bug that prevented tasks from starting due to a typo in the send proxy side effect handler.
This commit fixes a bug due to improper handling of the launcher ipc tunnel. When the tunnel closes, the launcher now does not attempt to send any messages, which prevents a crash like this from occurring.
This commit adjusts the logic surrounding registering for task events.
Now the launcher will register for events as soon as the adapter is
ready. This prevents any possibility of the task event chain not being
set up properly to forward events to the frontend.

This commit also hides console logs so they only show in dev mode and
renames the manager.html file to a more appropriate launcher.html
This commit fixes a bug where deactivating the frontend would prevent the task launcher from starting again. A code path to launch the main window was missing the call to start the launcher as well.
Copy link
Collaborator Author

@pr1sm pr1sm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just leaving a couple of reminders/questions I have before I forget them!

packages/frontend/.env.dev Show resolved Hide resolved
packages/frontend/lib/task/adapter.js Outdated Show resolved Hide resolved
We have a requirement to use instance methods within the Transformer subclasses, but the implementations don't use `this`. Since this is a valid exception to the rule, an eslint comment is added to the top of both to convey this.

See https://eslint.org/docs/rules/class-methods-use-this#exceptions for more details
@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

Seems like we get errors when trying to run at scale. I ran 50 tasks and got the following error message. The responsiveness of the app was also not that great. while running:
maxlistenerlimit

This commit adjusts the max listeners for the TaskManager and TaskRunner event listeners. This allows many tasks (>25) to run without producing memory leak warnings.
@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

Updating the max listeners helped, but I'm still seeing reduced responsiveness at ~50 tasks.

@walmat
Copy link
Owner

walmat commented Feb 22, 2019

Looks like the only issue was monitor/error delays aren't updating properly, other than that I'm trying to think of any other functionality and I can't..

@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

👍 I'll take a look into fixing that. Does swapping proxies work? Just thought of that

@walmat
Copy link
Owner

walmat commented Feb 22, 2019

👍 I'll take a look into fixing that. Does swapping proxies work? Just thought of that

Lemme spin up a few proxies to test

This commit updates the event handlers to allow responding to a bulk event. In this case the ID passed will be 'ALL'. This allows a single event to be emitted when adjusting a delay or webhook in the TaskManager for all tasks.

This also keeps the contract of purely using event based communication between the manager and runner.
@walmat
Copy link
Owner

walmat commented Feb 22, 2019

Updating the max listeners helped, but I'm still seeing reduced responsiveness at ~50 tasks.

I also noticed this testing on my i7 sandy bridge e running 40 tasks. Looks like the app is spawning 2,000+ threads for only 40 tasks for some reason.

This commit updates the default single thread TaskManager Implementation to have similar syntax as the SplitContextTaskManager. This ensures all TaskManger implementations work when used.
@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

Whoa, that's crazy -- not sure why that's happening!

Copy link
Owner

@walmat walmat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great man. I'll probably still have questions for the coming week or so that pop up, but this makes sense for the most part right now! I think the split out of the context managers is super handy.

@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

ready for merge? @walmat

@walmat
Copy link
Owner

walmat commented Feb 22, 2019

Let me do a full run through one more time in dev and prod mode to make sure! @pr1sm

@walmat
Copy link
Owner

walmat commented Feb 22, 2019

@pr1sm we're good to go in my opinion! No hiccups.

@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

When I get back to my computer, I'll change the defaults to use the thread manager, then we can test one more time and merge

This commit updates the default task manager to use the multi thread implementation. The set env var for prod is also updated to use thread instead of process.
@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

@walmat Ok I think this is ready for a final review, test, and merge!

@walmat
Copy link
Owner

walmat commented Feb 22, 2019

@walmat Ok I think this is ready for a final review, test, and merge!

All systems go for me! Tested all use cases in dev & prod.

@pr1sm
Copy link
Collaborator Author

pr1sm commented Feb 22, 2019

🚀 merging...

@pr1sm pr1sm merged commit af8b3d6 into b1.0.0-beta.6 Feb 22, 2019
@pr1sm pr1sm deleted the issue_192_task branch February 22, 2019 23:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:task-runner Related to Nebula's Task Runner package priority:urgent Issues that need to be solved right away type:enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants