Skip to content

Conversation

@ezaquarii
Copy link
Contributor

@ezaquarii ezaquarii commented Apr 13, 2020

Not all requests release connections, which leads to connection
pool starvation and lock-ups during files upload.

Apache's HTTP client handles "lost" connections by a GC
hook and removes unreachable objects from the pool.

However, this mechanism requires actual GC to occur, which
may not happen if the app is otherwise idle.

One way of observing this problem is to:

  1. start upload of ~30 decently sized photos (few mbytes)
  2. hang around in Uploads screen and observe progress bars
  3. stop the app using debugger and observe FileUploaderThread
    being blocked in MultiThreadedHttpConnectionManager.doGetConnection()
    (calling wait())
  4. when upload stalls, force GC using Android Studio profiler; this
    should unblock the connection pool and resume uploads

Increasing maximum number of allowed connections gives
more room for GC to kick in and reclaim stale connections,
which in turn should greatly improve stability of multi-file
uploads.

Other method would be to walk around the app, causing memory
allocations and triggering a GC as a side effect.

Signed-off-by: Chris Narkiewicz hello@ezaquarii.com

Not all requests release connections, which leads to connection
pool starvation and lock-ups during files upload.

Apache's HTTP client handles "lost" connections by a GC
hook and removes unreachable objects from the pool.

However, this mechanism requires actual GC to occur, which
may not happen if the app is otherwise idle.

One way of observing this problem is to:
1) start upload of ~30 decently sized photos (few mbytes)
2) hang round in Uploads screen and observe progress bars
3) stop the app using debugger and observe FileUploaderThread
   being blocked in MultiThreadedHttpConnectionManager.doGetConnection()
   (calling wait())
4) when upload stalls, force GC using Android Studio profiler; this
   should unblock the connection pool and resume uploads

Increasing maximum number of allowed connections gives
more room for GC to kick in and reclaim stale connections,
which in turn should greatly improve stability of multi-file
uploads.

Other method would be to walk around the app, causing memory
allocations and triggering a GC as a side effect.

Signed-off-by: Chris Narkiewicz <hello@ezaquarii.com>
@ezaquarii ezaquarii force-pushed the ezaquarii/increase-max-connections-in-http-client-pool branch from 4ab104d to 78e592b Compare April 13, 2020 23:08
@ezaquarii
Copy link
Contributor Author

@tobiasKaminsky @AndyScherzinger I believe we have some user reports of stale uploads... this is nasty workaround that should improve the situation.

Proper solution would require tracking down all leaks and eliminating them. HTTP method has explicit API to release the connection, so this should not be a massively difficult task.

In the meantime, this is a cheap work-around that seems to work.

While benchmarking it, my connection pool accumulated 10 connections max, just to drop to 2 when GC kicks in. Your mileage may vary.

@nextcloud-android-bot
Copy link
Collaborator

@ezaquarii
Copy link
Contributor Author

IT test failed: https://www.kaminsky.me/nc-dev/library-integrationTests/1509

I cannot see how this is caused by me. :) Flaky test?

@nextcloud-android-bot
Copy link
Collaborator

@nextcloud-android-bot
Copy link
Collaborator

Lint

TypemasterPR
Warnings11
Errors00

SpotBugs (new)

Warning TypeNumber
Bad practice Warnings14
Correctness Warnings38
Internationalization Warnings6
Malicious code vulnerability Warnings7
Multithreaded correctness Warnings3
Performance Warnings17
Security Warnings1
Dodgy code Warnings58
Total144

SpotBugs (master)

Warning TypeNumber
Bad practice Warnings14
Correctness Warnings38
Internationalization Warnings6
Malicious code vulnerability Warnings7
Multithreaded correctness Warnings3
Performance Warnings17
Security Warnings1
Dodgy code Warnings58
Total144

@ezaquarii
Copy link
Contributor Author

ezaquarii commented Apr 13, 2020

Possibly a solution for nextcloud/android#5758 and nextcloud/android#3715

@tobiasKaminsky
Copy link
Member

Nice trick!

Proper solution would require tracking down all leaks and eliminating them. HTTP method has explicit API to release the connection, so this should not be a massively difficult task.

We should do this (and I thought we are doing this, but better check it)…

@nextcloud-android-bot
Copy link
Collaborator

Lint

TypemasterPR
Warnings11
Errors00

SpotBugs (new)

Warning TypeNumber
Bad practice Warnings14
Correctness Warnings38
Internationalization Warnings6
Malicious code vulnerability Warnings7
Multithreaded correctness Warnings3
Performance Warnings17
Security Warnings1
Dodgy code Warnings58
Total144

SpotBugs (master)

Warning TypeNumber
Bad practice Warnings14
Correctness Warnings38
Internationalization Warnings6
Malicious code vulnerability Warnings7
Multithreaded correctness Warnings3
Performance Warnings17
Security Warnings1
Dodgy code Warnings58
Total144

@nextcloud-android-bot
Copy link
Collaborator

@AndyScherzinger AndyScherzinger merged commit 771c59e into master Apr 14, 2020
@delete-merged-branch delete-merged-branch bot deleted the ezaquarii/increase-max-connections-in-http-client-pool branch April 14, 2020 19:05
@AndyScherzinger AndyScherzinger added this to the NC Android lib 2.2.0 milestone Apr 14, 2020
@ezaquarii
Copy link
Contributor Author

ezaquarii commented Apr 14, 2020 via email

@tobiasKaminsky
Copy link
Member

It's design doesn't encourage me to invest more time into it...

Also we want to switch to okhttp, so it would be somehow a waste of time ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants