This article is the so-called “proof-of-concept” of creating a front-end application that works with the API via JSONP, that is, as they say, “cross-origin”. Also described is the organization of data in Redis.
For example, you can easily place on
jsfiddle.net a certain application, the back-end of which will be located on another domain.
Agree that a full-fledged working end product (requiring the presence of a server for centralizing data exchange) that is inside JSFiddle looks funny!
')

The purpose of the article is to share its current experience from two sides:
- JSONP + Long Polling Implementation
- Working with wonderful redis
Something like doing guys from
BackendLess .
What do we have
So, we have:
- Some kind of own server with Python 2.x on board
- Browser and access to JSFiddle.net
- The desire to build an API-over-JSONP
What i used
Jsonp
I think the reader does not need an explanation of what it is. And about the implementation - everything is done by one decorator:
def jsonp(fn): def wrapper(*args, **kwargs): callback = request.args.get('callback', None) if not callback: raise BadRequest('Missing callback argument.') return '{callback}({data});'.format( callback=callback, data=dumps(fn(*args, **kwargs)) ) wrapper.__name__ = fn.__name__ return wrapper
Redis
There is such a wonderful thing - Redis. As the developers say about it,
BSD licensed, advanced key-value cache and store. It can often be the strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs.
Or in a nutshell:
Redis is a powerful system for storing and caching data in a key-value format.
A little about Redis
If you are not familiar with Redis, I advise you to read about it at the office. site, because not all the details of working with it will be described below.Actually, Redis itself works as a separate daemon, and from the Python script we access it through a fairly simple module connector of the same name.
We can create a key and assign it to:
- Scalar value (actually a string )
- List
- Array
- Lots of
- Set up
But! We cannot make an array of arrays, for example. Therefore, in this case, you will have to make a key with a list of indexes and a key for each index. Also, due to the lack of sampling by values (a la WHERE in SQL), sometimes you have to make lists with reverse mapping, for example, to search for a user ID by nickname and to search for a user nickname by its ID.
Roughly speaking: what is a table in SQL will be a
list of indices and a
set of arrays in Redis. It is also customary to separate parts of the key with a colon.
Example in SQL: 1 table - with fields user_id, user_name, user_email and 5 records.
The analogy in Redis: 1 list and 5 arrays - a list of
users with data [1, 2, 3, 4, 5] and 5 arrays with names (keys) of the form
user: X with data {id: X, name: Y, email: Z}, as well as several arrays with a reverse link, for example, nicknames with values {andrew: 1, john: 2, mike: 3, ...}
Why redis?
- In Redis, you do not need to specify data structures: just put them there.
- We can do CRUD ( Create-Read-Update-Delete ) with data located in the Redis base, and also use the built-in locking mechanism - by the way, it greatly simplifies the implementation of the long polling mechanism.
- No JOIN or WHERE Redis is not able, and should not - it only stores primitives, maximum lists or associative arrays from primitives. But this is not a minus, but an additional discretion and incentive for expanding thinking, different from the SQL and NoSQL-DBMS patterns.
The structure of the key-value storage system database
Here is the data in our Redis at the moment when Andrew wrote the message and John wrote the message, but the first was read by everyone except the shirt, and the second - only by John himself. But for a few moments, all
user: X: messages will be cleared, because A poling timeout will occur and the data will go to the clients. Those.
user: X: messages - this is such a container for the not yet received messages of a certain user.

Long polling
With Redis you can easily implement
long polling . The approximate algorithm is as follows:
- We request in Redis (with the LLEN command) whether there is a message for the client right now in the list of messages, if there is, return messages and clean the list with DEL
- If there are no messages, we request them again, but this time by the BLPOP team , which will block the active stream until the data appears or the timeout expires. By unlocking, we return the result from Redis to the client, in which there will be either a message just received, or nothing.
"Fighting team, go ahead!"
Front end for testing:
jsfiddle.net/andunai/kcdtzdwwBack -end source code:
bitbucket.org/AndrewDunai/nobackend-chat-dirtyFullscreen version:
jsfiddle.net/andunai/kcdtzdww/embedded/resultPost Scriptum
I am very pleased that you have read this far. I, as always, welcome any comments and suggestions.
I hope, habraeffekt not much touches my little VPS.
Thanks for attention!
UPDATE: the repository is now public, accidentally made it private when created.