daisycrego / jbg-admin

Admin app for Jill Biggs Group follow-up boss event management
1 stars 0 forks source link

Paginated queries - /events and /leads apis #40

Closed daisycrego closed 3 years ago

daisycrego commented 3 years ago

Previous data sizes resulted in latency with search loads --> current larger data sizes are leading to outright failed searches. Heroku logs show that searches which will return all data rows exceed JS heap memory:

2021-08-19T17:15:02.314891+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=POST path="/api/events/search" host=jbg-admin.herokuapp.com request_id=57883254-4f29-413a-af0c-58174ddcc641 fwd="108.53.25.92" dyno=web.1 connect=1ms service=30024ms status=503 bytes=0 protocol=https
2021-08-19T17:15:07.298309+00:00 app[web.1]: 
2021-08-19T17:15:07.298318+00:00 app[web.1]: <--- Last few GCs --->
2021-08-19T17:15:07.298319+00:00 app[web.1]: 
2021-08-19T17:15:07.298320+00:00 app[web.1]: [4:0x5758fd0]   707838 ms: Mark-sweep 250.9 (258.0) -> 250.4 (258.0) MB, 818.7 / 0.0 ms  (average mu = 0.158, current mu = 0.033) allocation failure scavenge might not succeed
2021-08-19T17:15:07.298320+00:00 app[web.1]: [4:0x5758fd0]   708516 ms: Mark-sweep 251.4 (258.0) -> 250.8 (258.5) MB, 657.3 / 0.0 ms  (average mu = 0.103, current mu = 0.031) allocation failure scavenge might not succeed
2021-08-19T17:15:07.298321+00:00 app[web.1]: 
2021-08-19T17:15:07.298411+00:00 app[web.1]: 
2021-08-19T17:15:07.298412+00:00 app[web.1]: <--- JS stacktrace --->
2021-08-19T17:15:07.298412+00:00 app[web.1]: 
2021-08-19T17:15:07.298413+00:00 app[web.1]: ==== JS stack trace =========================================
2021-08-19T17:15:07.298413+00:00 app[web.1]: 
2021-08-19T17:15:07.298414+00:00 app[web.1]: 0: ExitFrame [pc: 0x13d8b79]
2021-08-19T17:15:07.298414+00:00 app[web.1]: 1: StubFrame [pc: 0x136baa1]
2021-08-19T17:15:07.298415+00:00 app[web.1]: Security context: 0x275035040921 <JSObject>
2021-08-19T17:15:07.298416+00:00 app[web.1]: 2: cloneObject(aka cloneObject) [0x5fe440bcbe1] [/app/node_modules/mongoose/lib/helpers/clone.js:~103] [pc=0x261e7823ab79](this=0x309fa5d804b9 <undefined>,0x3042409b8ee9 <Object map = 0x2dc67c9493b1>,0x013a5efd2529 <Object map = 0x2dc67c950481>,0x309fa5d804b9 <undefined>)
2021-08-19T17:15:07.298416+00:00 app[web.1]: 3: cloneObject(aka cloneObject) [0x5fe440bcbe1] [/a...
2021-08-19T17:15:07.298416+00:00 app[web.1]: 
2021-08-19T17:15:07.298443+00:00 app[web.1]: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
2021-08-19T17:15:07.299380+00:00 app[web.1]: 1: 0xa0c020 node::Abort() [node]
2021-08-19T17:15:07.300063+00:00 app[web.1]: 2: 0xa0c42d node::OnFatalError(char const*, char const*) [node]
2021-08-19T17:15:07.300771+00:00 app[web.1]: 3: 0xb8130e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
2021-08-19T17:15:07.301495+00:00 app[web.1]: 4: 0xb81689 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
2021-08-19T17:15:07.302286+00:00 app[web.1]: 5: 0xd2fb95  [node]
2021-08-19T17:15:07.303081+00:00 app[web.1]: 6: 0xd30226 v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [node]
2021-08-19T17:15:07.303889+00:00 app[web.1]: 7: 0xd3ea99 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
2021-08-19T17:15:07.304698+00:00 app[web.1]: 8: 0xd3f8d5 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
2021-08-19T17:15:07.305520+00:00 app[web.1]: 9: 0xd423ac v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [node]
2021-08-19T17:15:07.306313+00:00 app[web.1]: 10: 0xd08f84 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [node]
2021-08-19T17:15:07.307243+00:00 app[web.1]: 11: 0x105532e v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [node]
2021-08-19T17:15:07.308170+00:00 app[web.1]: 12: 0x13d8b79  [node]
2021-08-19T17:15:07.370588+00:00 heroku[router]: at=error code=H13 desc="Connection closed without response" method=POST path="/api/events/search" host=jbg-admin.herokuapp.com request_id=09f35974-222b-4d16-b528-85b2e10b28be fwd="108.53.25.92" dyno=web.1 connect=1ms service=4844ms status=503 bytes=0 protocol=https
2021-08-19T17:15:07.451243+00:00 heroku[web.1]: Process exited with status 134
2021-08-19T17:15:07.590923+00:00 heroku[web.1]: State changed from up to crashed
2021-08-19T17:15:07.620903+00:00 heroku[web.1]: State changed from crashed to starting
daisycrego commented 3 years ago

solution

paginated queries Search page’s queryState includes page # and page size. At the server controllers for listing events and leads data, use the page to derive a portion of the data to send back. See about paginated queries from mongo- can we pass page /offset/etc in the find calls? Do we need to retrieve all data and then slice it up (much slower)?

daisycrego commented 3 years ago

The quickest solution to implementing pagination is something like this:

db.history.find({ customerId: 7000000 })
            .sort({ date: 1 })
            .skip(0)
            .limit(1000)

But we might run into problems with latency for the larger pages: https://www.mongodb.com/blog/post/paging-with-the-bucket-pattern--part-1

daisycrego commented 3 years ago

Implemented paginated queries. Seems to work for more of the cases, much faster. May still have the higher page number issue described in the link, but for now ok.