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

perf: reduce import overhead on background jobs #25459

Merged
merged 3 commits into from
Mar 15, 2024

Conversation

ankush
Copy link
Member

@ankush ankush commented Mar 15, 2024

Avoids 7MB of overhead and cleanup costs for each background job.

Memory profile of worker horse doing frappe.ping

image

After

image

Also, several other modules are loaded instantly on new jobs. In worker pool we can save on this CPU cost by preloading (paying shared memory cost). This increases memory usage of 8 workers by 20MB but reduces import overheads on each job by almost 60-70%

image


performing 100 job (frappe.ping) - good enough proxy for overheads.

Before:

λ bench worker-pool --num-workers=8 --burst > /dev/null  
8.67s user 5.18s system 491% cpu 2.815 total

After:

λ time bench worker-pool --num-workers=8 --burst > /dev/null
1.71s user 2.56s system 179% cpu 2.376 total

performing 100 job (frappe.email.queue.flush) - realistic work

Before:

λ time bench worker-pool --num-workers=8 --burst > /dev/null
26.98s user 11.11s system 597% cpu 6.378 total

After:

λ time bench worker-pool --num-workers=8 --burst > /dev/null
8.61s user 4.73s system 510% cpu 2.613 total

Avoids 7MB of overhead and cleanup costs for each background job 🎉
@ankush ankush requested a review from a team as a code owner March 15, 2024 05:21
@ankush ankush requested review from akhilnarang and removed request for a team March 15, 2024 05:21
@github-actions github-actions bot added the add-test-cases Add test case to validate fix or enhancement label Mar 15, 2024
@ankush ankush added backport version-14-hotfix backport to version 14 backport version-15-hotfix Backport the PR to v15 and removed add-test-cases Add test case to validate fix or enhancement labels Mar 15, 2024
@ankush
Copy link
Member Author

ankush commented Mar 15, 2024

Analyzing typical imports that we can save for worker-pool:

  • safe_exec - 6mb
  • requests - 5mb
  • PIL - 1.5mb
  • filetype - 1.4mb
  • SQLParse - 2mb
  • bs4 - 4.3mb
  • pypdf - 5.2

@ankush ankush marked this pull request as draft March 15, 2024 05:45
@ankush
Copy link
Member Author

ankush commented Mar 15, 2024

Some python shenanigans, if I explicitly import frappe in local scope then it works fine.

λ bench worker-pool
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/ankush/benches/develop/apps/frappe/frappe/utils/bench_helper.py", line 128, in <module>
    main()
  File "/home/ankush/benches/develop/apps/frappe/frappe/utils/bench_helper.py", line 34, in main
    FrappeCommandGroup(commands=commands)(prog_name="bench")
  File "/home/ankush/benches/develop/env/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ankush/benches/develop/env/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/home/ankush/benches/develop/env/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ankush/benches/develop/env/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ankush/benches/develop/env/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ankush/benches/develop/env/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/ankush/benches/develop/apps/frappe/frappe/commands/scheduler.py", line 225, in start_worker_pool
    start_worker_pool(
  File "/home/ankush/benches/develop/apps/frappe/frappe/utils/background_jobs.py", line 329, in start_worker_pool
    if frappe._tune_gc:
       ^^^^^^
UnboundLocalError: cannot access local variable 'frappe' where it is not associated with a value

@ankush ankush marked this pull request as ready for review March 15, 2024 05:53
@ankush ankush enabled auto-merge March 15, 2024 05:54
@ankush ankush removed the backport version-14-hotfix backport to version 14 label Mar 15, 2024
@ankush ankush changed the title perf: avoid importing posthog if not required perf: reduce import overhead on background jobs Mar 15, 2024
@ankush ankush merged commit b6f65ea into frappe:develop Mar 15, 2024
23 checks passed
@ankush ankush deleted the post_hog_memory_hog branch March 15, 2024 06:13
ankush added a commit that referenced this pull request Mar 15, 2024
…5460)

* perf: avoid importing posthog if not required

Avoids 7MB of overhead and cleanup costs for each background job 🎉

(cherry picked from commit 3226717)

* perf: preload modules in worker pool

(cherry picked from commit 0d6ec13)

* perf: import sentinal locally

(cherry picked from commit b7a5884)

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
frappe-pr-bot pushed a commit that referenced this pull request Mar 19, 2024
# [15.18.0](v15.17.3...v15.18.0) (2024-03-19)

### Bug Fixes

* add params in make_request arguments ([#25418](#25418)) ([18cf09b](18cf09b))
* allow transitioning to long text (backport [#25419](#25419)) ([#25475](#25475)) ([dbb326e](dbb326e))
* avoid closing filter popover on any date picker interactions ([cd98a21](cd98a21))
* Avoid setting filter on now/today button ([592e6f9](592e6f9))
* better filename for prepared report ([8eb1b24](8eb1b24))
* child table rating fields ([#25433](#25433)) ([#25436](#25436)) ([6f242ca](6f242ca))
* consider all datepicker elements ([#25426](#25426)) ([361fbfe](361fbfe))
* **ControlText:** Preserve indentation when read only ([#25262](#25262)) ([#25469](#25469)) ([c783f22](c783f22))
* debounce filter refresh ([9b75187](9b75187))
* default filter setup on todo list ([#25455](#25455)) ([#25464](#25464)) ([21e1280](21e1280))
* dont add trailing decimal separator ([#25389](#25389)) ([#25391](#25391)) ([760d9b2](760d9b2))
* dont add useless distinct clause ([8891e8e](8891e8e))
* dont render very large reports, offer export instead ([3f0760c](3f0760c))
* dont show tooltip if already limited ([#25361](#25361)) ([eb8b9f4](eb8b9f4))
* escape text types before setting disp area ([#25520](#25520)) ([#25523](#25523)) ([bc83b24](bc83b24))
* escape value in multiselect pill ([#25516](#25516)) ([#25518](#25518)) ([236a3b5](236a3b5))
* exclude irrelevant regional links ([#25510](#25510)) ([#25512](#25512)) ([9fe8b6a](9fe8b6a))
* filters can use more than 140 chars ([2d2b4a9](2d2b4a9))
* handle distinct for fieldname ([#25511](#25511)) ([#25515](#25515)) ([9168b0f](9168b0f))
* handle invalid fetch from split ([fa131ca](fa131ca))
* handle meta.fields being undefined ([#25539](#25539)) ([01cca38](01cca38))
* handle parent rename in child workspace ([ef3d068](ef3d068))
* hide datepicker after picking date ([d91a2b8](d91a2b8))
* **json_handler:** handle `uuid.UUID` ([ebaaa6b](ebaaa6b)), closes [#25242](#25242)
* Log ipython commands (backport [#25364](#25364)) ([#25368](#25368)) ([a2ebb4e](a2ebb4e))
* log mariadb console usage ([9797457](9797457))
* log psql console usage as well (backport [#25417](#25417)) ([#25423](#25423)) ([f0fa5d1](f0fa5d1))
* prevent TypeError if doc not defined ([#25540](#25540)) ([6b23504](6b23504))
* **QuickEntry:** Don't allow Tab Breaks ([#24950](#24950)) ([#25468](#25468)) ([a31943e](a31943e))
* **recorder:** handle frappe.db.sql(run=0) ([#25450](#25450)) ([#25454](#25454)) ([d130777](d130777))
* Respect document language in communication ([#25402](#25402)) ([#25403](#25403)) ([0d09b51](0d09b51))
* show attachments on notifications too ([#25443](#25443)) ([#25445](#25445)) ([371fa09](371fa09))
* skip setting of contact full name if its too long ([#25509](#25509)) ([d5685d7](d5685d7))
* skip virtual doctype in tags ([f18ac26](f18ac26))
* Skip virtual doctype rename for dynamic links ([#25479](#25479)) ([#25481](#25481)) ([3353488](3353488))
* Skip virtual doctypes while renaming ([#25473](#25473)) ([#25478](#25478)) ([aaacc51](aaacc51))
* support child tables in count with limit ([d8a797b](d8a797b))
* traceback colours ([#25356](#25356)) ([b6d2785](b6d2785))
* **UX:** let user see actual count on click ([5c1bca8](5c1bca8))
* validate homepage paths (backport [#25409](#25409)) ([#25412](#25412)) ([0aeaeeb](0aeaeeb))
* we want `DF.Literal[None]`, not `DF.LiteralNone` ([#25394](#25394)) ([f008eeb](f008eeb))

### Features

* connect to redis sentinel for redis cache ([#25398](#25398)) ([#25446](#25446)) ([498b1a4](498b1a4))
* debug stuck process by sending SIGUSR1 (backport [#25502](#25502)) ([#25527](#25527)) ([6c8cc5c](6c8cc5c))
* move bulk print operation to the background (backport [#25358](#25358)) ([#25397](#25397)) ([513487e](513487e))
* Store printed PDF attachments on communication ([#25439](#25439)) ([#25444](#25444)) ([bd15abc](bd15abc))
* support countig till a limit ([615800f](615800f))

### Performance Improvements

* Avoid ordering in count query ([#25451](#25451)) ([#25452](#25452)) ([07aadd3](07aadd3))
* compact prepared report files ([3adbb35](3adbb35))
* don't extract backups whenever possible ([#25350](#25350)) ([9c6fb8a](9c6fb8a)), closes [/github.com//pull/24898#discussion_r1521076386](https://github.com//github.com/frappe/frappe/pull/24898/issues/discussion_r1521076386)
* reduce import overhead on background jobs (backport [#25459](#25459)) ([#25460](#25460)) ([eab5b8d](eab5b8d))
* show estimated count on list view ([7ee9719](7ee9719))
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
backport version-15-hotfix Backport the PR to v15
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant