Sorl-thumbnail + DigitalOcean + Amazon S3 slowness - sorl-thumbnail

Due to AWS EC2 being kind of expensive, I have tried to migrate to DigitalOcean, but I found out that rendering a page with thumbnails are kind of slow from DigitalOcean with Amazon S3 being the file storage. (Running from EC2 is pretty fast I assume the traffic within Amazon)
Symptoms:
Initial load was very very slow, due to thumbnail creation
Subsequent load was very slow also, but not as slow as initial load
I have the following settings:
STATICFILES_STORAGE = DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
THUMBNAIL_KVSTORE = values.Value('sorl.thumbnail.kvstores.cached_db_kvstore.KVStore')
and I can see sorl-thumbnail generates cache values in the KVStore in the database. But it seems to me that it still checks for file existence on S3 before rendering the thumbnail. This is contradict to the documentation:
It is worth noting that sorl-thumbnail does not check if source or thumbnail exists if the thumbnail key is found in the Key Value Store.
I have searched on SO and google and saw some related posts, but they were 4 years old and don't seem to have conclusive answers.

After much debugging, I finally nailed it, the problem is buried deep inside s3boto.py inside django-storages
Problem:
def url(self, name):
name = self._normalize_name(self._clean_name(name))
if self.custom_domain:
return "%s//%s/%s" % (self.url_protocol,
self.custom_domain, name)
return self.connection.generate_url(self.querystring_expire,
method='GET', bucket=self.bucket.name, key=self._encode_name(name),
query_auth=self.querystring_auth, force_http=not self.secure_urls)
I didn't have custom_domain setup so for every thumbnail it was trying to access S3 API to construct the URL.
After defining AWS_S3_CUSTOM_DOMAIN and AWS_S3_URL_PROTOCOL it's working lightening fast.

Related

Couchbase Sync-Gateway Multiple Clients

I'am currently playing around with the Couchbase Sync-Gateway and have built a demo app.
What is the intended behavior if a user logs in with the same username on a different device (which has an empty database) or if he deleted the local database?
I'am expecting that all the data from the server should get synced back to the clients.
Is this correct?
My problem is that if i'am deleting the database or login from a different device, nothing will get synced.
Ok i figured it out and it's exactly how i thought it would be.
If i log in from a different device i get all the data synced automatically.
My problem was the missing sync function. I thought it will use a default and route all documents to the public channel automatically.
I'am now using the following simple sync-function:
"sync": `function (doc, oldDoc) {
channel('!');
access('demo#example.com', '*');
}`
This will simply route all documents to the public channel and grant my demo-user access to it.
I think this shouldn't be used in production but it's a good starting point for playing around.
Now everything is working fine.
Edit: I've now found the missing info:
https://docs.couchbase.com/sync-gateway/current/configuration-properties.html#databases-this_db-sync
If you don't supply a sync function, Sync Gateway uses the following default sync function
...
The channels property is an array of strings that contains the names of the channels to which the document belongs. If you do not include a channels property in a document, the document does not appear in any channels.

Couchbase Java SDK times out with BUCKET_NOT_AVAILABLE

I am doing a lookup operation Couchbase Java SDK 3.0.9 which looks like this:
// Set up
bucket = cluster.bucket("my_bucket")
collection = bucket.defaultCollection()
// Look up operation
val specs = listOf(LookupInSpecStandard.get("hash"))
collection.lookupIn(id, specs)
The error I get is BUCKET_NOT_AVAILABLE. Here are is the full message:
com.couchbase.client.core.error.UnambiguousTimeoutException: SubdocGetRequest, Reason: TIMEOUT {"cancelled":true,"completed":true,"coreId":"0xdb7f8e4800000003","idempotent":true,"reason":"TIMEOUT","requestId":608806,"requestType":"SubdocGetRequest","retried":39,"retryReasons":["BUCKET_NOT_AVAILABLE"],"service":{"bucket":"export","collection":"_default","documentId":"export:main","opaque":"0xcfefb","scope":"_default","type":"kv"},"timeoutMs":15000,"timings":{"totalMicros":15008977}}
The strange part is that this code hasn't been touched for months and the lookup broke out of a sudden. The CB cluster is working fine. Its version is
Enterprise Edition 6.5.1 build 6299.
Do you have any ideas what might have gone wrong?
Note that in Couchbase Java SDK 3.x, the Cluster::bucket method returns instantly, and continues opening a bucket in the background. So the first operation you perform - a lookupIn here - needs to wait for that resource opening to complete before it can proceed. It looks like it took a little longer to access the Couchbase bucket than usual and you got a timeout.
I recommend using the Bucket::waitUntilReady method after opening a bucket, to block until the resource opening is complete:
bucket = cluster.bucket("my_bucket")
bucket.waitUntilReady(Duration.ofMinutes(1));
This problem can occur because of firewall. You need to allow these ports.
Client-to-node
Unencrypted: 8091-8097, 9140 [3], 11210
Encrypted: 11207, 18091-18095, 18096, 18097
You can check more from below
https://docs.couchbase.com/server/current/install/install-ports.html#_footnotedef_2

How can Firebase be used for WebRTC signalling?

I've achieved a successful WebRTC connection using Firebase - but it only works if both users are on the same local network. I've tried using using different STUN servers, and even used TURN, but with the same result.
Is there any sample code or any place which shows how to achieve basic signalling for WebRTC using Firebase? I've tried looking at the docs, and there doesn't seem to be. What confuses me more is that my app works in the local network, but not outside of it.
Btw, I've also used PubNub and I've no problem using that to achieve signalling (even across networks).
I've set up a reference to my data like this
myDataRef = new Firebase('https://<myapp>.firebaseio.com');
myDataRef.on('value', function(snapshot) {
var json = snapshot.val();
and I communicate messages like so:
myDataRef.set(json);
The json message will include the action type (candidate, or offer or answer) and will also include the SDP, if required.
Any help on this will be appreciated!

InstanceContextMode.Single in WCF wsHttpBinding,webHttpBinding and REST

I have recently started development on a relatively simple WCF REST service which returns JSON formatted results. At first everything worked great, and the service was quickly up and running.
The main function of the service is to return a large chunk of data extracted from a database. This data rarely changes, so I decided to try and setup a caching mechanism to speed things up. To do this I planned to set InstanceContextMode.Single and ConcurrencyMode.Multiple, and then with some thread locks, safely return a static cached result. Every 5 minutes or so, or whenever IIS decides to clear everything, the data would be re-fetched from the database.
My issue is InstanceContextMode.Single does not behave as expected. My understanding is a single instance of my WCF service class should be created and maintained. However the behaviour I have is a completely new instance of my Class is created per call. This include re-initialising all static variables.
I tried changing the web service from webHttpBinding (used for REST) to wsHttpBinding and using the service as a SOAP config, but this results in exactly the same behaviour.
What am I doing wrong!!! Have spent way too long trying to figure this out.
Any help would be great!.
Strange, can you try this and tell me what happen then?
ServiceThrottlingBehavior ThrottleBehavior = new ServiceThrottlingBehavior();
ThrottleBehavior.MaxConcurrentSessions = 1;
ThrottleBehavior.MaxConcurrentCalls = 1;
ThrottleBehavior.MaxConcurrentInstances = 1;
ServiceHost Host = ...
Host.Description.Behaviors.Add(ThrottleBehavior);
And [how] do you know your single service instance isn't "Single"? You saw multiple database connection from profiler? Is that what suggested to you why your service isn't a single instance? From your service operation implementation, do you do some of the work on a separate thread?

How do I save geolocation data for an HTML5 or trigger.io app for path mapping later?

Im creating an app that needs to track the location of the user (with their knowledge, like a running app) so that I can show them their route later. Should I use HTML5 with some timeout interval to save the coordinates every N seconds and if so, how often should I save the data and how should I save it (locally using local storage or post it to the server?)
Also, what is the easiest way to display the map of where the user has been later?
Has anyone done anything like this before?
The timeout interval for forge.geolocation is up to you and the balance of responsiveness of your application. Also, network traffic is expensive. So maybe you can buffer... say the last 10 geopositions... and then Http post (or whatever... see Parse below) in bulk? And since the geo data sounds like temporary device data why would there be a need to persist using forge.prefs? Unless maybe you need to the app to work "offline"?
For permanent storage I would look at Parse (generous free plan) and their Parse.GeoPoint class via their Javascript or REST Api as one possible solution. They have some nifty methods like (kilometersTo, milesTo, radiansTo) - https://parse.com/docs/js/symbols/Parse.GeoPoint.html