Node.js-based Client-Server Prime Number Verification
A simple client-server prime number tester with TDD in mind
- Quickly verify prime and non-prime numbers for primality
- Fully tested client and server-side APIs for correctness
- Handle concurrent client requests in parallel
docker-compose -f docker-compose.server.yml up --build
JPRIMER_START=12345678901234567890123456789012345678901234567890 node client.js --JPRIMER_COUNT=100000
Note: Command-line arguments via
nconf
seem to only be able to be so large, so use environment variables ifJPRIMER_START
orJPRIMER_COUNT
are huge
- Download and install nvm for your operating system
nvm install 10.15.1
nvm use 10.15.1
cd client && npm install && cd ../server && npm install
npm install -g jest
- Install
vscode-jest
extension for VSCode - Launch
docker-compose -f docker-compose.debug.yml up --build
Docker server will now be running and the client containerized process is waiting for a debugger to attach
It is also possible to run the server using docker-compose.server.yml
and launch the client either as a container or directly from VSCode.
cd client && jest && cd ../server && jests
As of the last few checkins, using client-side throttling of requests, this shouldn't be a problem. A user can experiment with setting the
JPRIMER_START
andJPRIMER_COUNT
environment variables to search for a near-limitless number of primes
- The node client process, if unbounded, will make as many promises at once as possible
- Performing a near limitless number of requests (as is made possible through the use of JSBN) at once is a "bad idea," and will exhaust all available client memory quite readily
- Below, you can see an 8GB client machine fall over at roughly 400,000 requests, after an elapsed 38 seconds... without a single request having yet been sent -- something can be done to enable large search regions
numWorkers: 436556
<--- Last few GCs --->
[23711:0x3f308b0] 36728 ms: Mark-sweep 1399.3 (1426.2) -> 1399.1 (1426.2) MB, 1189.1 / 0.0 ms (+ 24.6 ms in 11 steps since start of marking, biggest step 7.4 ms, walltime since start of marking 1224 ms) (average mu = 0.061, current mu = 0.011) allocat
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0x15cfee85be1d]
Security context: 0x3fa98801e6e1 <JSObject>
1: getColorDepth [0x2ad92af3f239] [internal/tty.js:~70] [pc=0x15cfee86be92](this=0x2ad92af5dbc1 <WriteStream map = 0x14d8c56ceac9>,/* anonymous */=0x065c4e5826f1 <undefined>)
2: arguments adaptor frame: 0->1
3: /* anonymous */ [0x11f6f1c70671] [console.js:~189] [pc=0x15cfee86c1ea](this=0x1f720ae8bb39 <Console map = 0x14d8c56d10f1>,args=0x21e9cd7b...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x8dc1c0 node::Abort() [node]
2: 0x8dc20c [node]
3: 0xad60ae v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
4: 0xad62e4 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
5: 0xec3972 [node]
6: 0xec3a78 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [node]
7: 0xecfb52 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
8: 0xed0484 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
9: 0xed30f1 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]
10: 0xe9c574 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [node]
11: 0x113beae v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [node]
12: 0x15cfee85be1d
Aborted
- docker-ce 18.09+
- docker-compose 1.22+
- nvm 0.34.0
- Node.js 10.15.1
- Jest 24.1.0
Testing a Node.JS Application Within a Docker Container