vsoch / freegenes

FreeGenes BioNode with Django
https://vsoch.github.io/freegenes/
Mozilla Public License 2.0
2 stars 4 forks source link

Cache for Twist #61

Closed vsoch closed 5 years ago

vsoch commented 5 years ago

For large requests to the Twist API, for operations that can run unattended I'm setting them up to be redis tasks (run async when the server has free time). However, for some large queries (e.g., getting all the plate ids associated with an order for the user to provide containers and names for) we don't have a choice but to make the user wait. For the time being, I'm going to add a spinner, but ideally when the user loads the order page (where the button can be clicked to import) the server would issue the request, and cache it to make the eventual click happen instantly.

vsoch commented 5 years ago

Right now we are using the default memory cache:

CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
            }
}

so it will need to be investigated the upper limits of this cache, and how it can (or can't) be used for this purpose. If not, we need another simple solution - the data structure is typically a list of ~300-500 dicts - the object I'm currently working with is:

> len(rows)                                                                                                   
408

sys.getsizeof(rows)                                                                                         
 3344 # bytes
Koeng101 commented 5 years ago

Seems like 3kb of memory isn't that much to hold. Can it not do that much?

vsoch commented 5 years ago

It can, I just want to implement a nice function / workflow to do the cache (and check that it won't exceed, for some edge case).

Also! I think most of our discussion today is ready for testing on the server - it's too late here and I'm too nervous to deploy it today, but I'll get it up and live tomorrow! https://github.com/vsoch/freegenes/pull/62.

vsoch commented 5 years ago

okay here is how I think we can easily do this - given "default" mem cache defined in settings:

from django.core.cache import caches
cache = caches['default']

# This is an example of looking up a key that doesn't exist
data = cache.get('dontexist')
data

# And now setting one - a list will work (60 seconds)
cache.set('doesexist', [1,2,3,4,5], 60)
data = cache.get('doesexist')
# data --> [1,2,3,4,5]

# dictionaries don't work! But we can json.dumps them to a string
import json
cache.set('doesexist', json.dumps({1:1}), 60)
data = cache.get('doesexist')

So what I'll try doing is, given that someone navigates to a Twist order details page, I'll fire off a function to do the query (and save to cache for 60 seconds). Since it's local memory we can't actually use a worker (different container) but we can run it on the server.

vsoch commented 5 years ago

okay this is implemented - when the user goes to the form to import an order, we submit a POST to run the (longer to take) API request in advance, and then it gets cached for 10 minutes. https://github.com/vsoch/freegenes/blob/master/fg/apps/factory/views/twist.py#L120.

I can't share the cache with the worker that runs the final task, but this is okay because a user isn't waiting on it.