Домой Edit me on GitHub

2019-06-19

Каналы передачи данных | Сетевое программирование | Базы данных | Основы Веб-программирования

Кэширование

Beaker

См.также

Beaker — это библиотека предназначенная, для кэширования и создания сессии, как в веб-приложениях, так и в чистых Python скриптах. Имеет WSGI-middleware для WSGI-приложений и декоратор (Декораторы) для простых приложений.

Сессии

Создание

common.py - функция get_session создает сессию
1
2
3
4
5
6
7
8
from beaker.session import Session


def get_session(request={}, **kwargs):
    """A shortcut for creating :class:`Session` instance"""
    options = {}
    options.update(**kwargs)
    return Session(request, **options)
0.session.py - сохранение данных в сессии
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-
from pprint import pprint
from common import get_session

if '__main__' in __name__:
    """Test if the data is actually persistent across requests"""
    session = get_session()
    session['Suomi'] = 'Kimi Räikkönen'
    session['Great Britain'] = 'Jenson Button'
    session['Deutchland'] = 'Sebastian Vettel'
    session.save()
    print("Session ID: " + session.id)
    pprint(session)

    print
    print("Check session")
    session2 = get_session(id=session.id)
    assert 'Suomi' in session2
    assert 'Great Britain' in session2
    assert 'Deutchland' in session2

    assert session2['Suomi'] == 'Kimi Räikkönen'
    assert session2['Great Britain'] == 'Jenson Button'
    assert session2['Deutchland'] == 'Sebastian Vettel'
    print("OK")
    print
    assert session2['Russian'] == 'Alexey Popov'
Результат выполнения программы 0.session.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Session ID: a628f9a5f15e48f99b06d3a710791499
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi Räikkönen',
 '_accessed_time': 1475907168.6420162,
 '_creation_time': 1475907168.6420162}
Check session
OK
Traceback (most recent call last):
  File "0.session.py", line 27, in <module>
    assert session2['Russian'] == 'Alexey Popov'
KeyError: 'Russian'

Удаление

1.session.delete.py - удаление сессии
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# -*- coding: utf-8 -*-
from pprint import pprint
from common import get_session

if '__main__' in __name__:
    """Test if the data is actually persistent across requests"""
    session = get_session()
    session['Suomi'] = 'Kimi Räikkönen'
    session['Great Britain'] = 'Jenson Button'
    session['Deutchland'] = 'Sebastian Vettel'
    session.save()
    print("Session ID: " + session.id)
    pprint(session)

    session.delete()
    print
    print("Delete session")
    print("Session ID: " + session.id)
    pprint(session)

    assert 'Suomi' not in session
    assert 'Great Britain' not in session
    assert 'Deutchland' not in session
    assert 'Russian' not in session
Результат выполнения программы 1.session.delete.py
1
2
3
4
5
6
7
8
9
Session ID: f0f6d2a4e02841e49d97ee5ba7ac3985
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi Räikkönen',
 '_accessed_time': 1475907306.4009516,
 '_creation_time': 1475907306.4009516}
Delete session
Session ID: f0f6d2a4e02841e49d97ee5ba7ac3985
{}

Откат изменений

2.session.revert.py - откат изменений в сессии
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding: utf-8 -*-
from pprint import pprint
from common import get_session

if '__main__' in __name__:
    """Test if the data is actually persistent across requests"""
    session = get_session()
    session['Suomi'] = 'Kimi Räikkönen'
    session['Great Britain'] = 'Jenson Button'
    session['Deutchland'] = 'Sebastian Vettel'
    session.save()
    print("Session ID: " + session.id)
    pprint(session)

    session2 = get_session(id=session.id)
    del session2['Suomi']
    session2['Great Britain'] = 'Lewis Hamilton'
    session2['Deutchland'] = 'Michael Schumacher'
    session2['España'] = 'Fernando Alonso'

    print
    print("Modified session")
    print("Session ID: " + session2.id)
    pprint(session2)

    session2.revert()

    print
    print("Revert session")
    print("Session ID: " + session2.id)
    pprint(session2)
Результат выполнения программы 2.session.revert.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Session ID: 2887074c36af4aadad354a79bbdb2cc4
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi Räikkönen',
 '_accessed_time': 1475907344.1409602,
 '_creation_time': 1475907344.1409602}
Modified session
Session ID: 2887074c36af4aadad354a79bbdb2cc4
{'Deutchland': 'Michael Schumacher',
 'España': 'Fernando Alonso',
 'Great Britain': 'Lewis Hamilton',
 '_accessed_time': 1475907344.1411998,
 '_creation_time': 1475907344.1409602}
Revert session
Session ID: 2887074c36af4aadad354a79bbdb2cc4
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi Räikkönen',
 '_accessed_time': 1475907344.1411998,
 '_creation_time': 1475907344.1409602}

Хранение в файловой системе

По умолчанию сессии хранятся в оперативной памяти и при завершении программы удаляются. Чтобы сессии хранились постоянно, нужно указать место на диске:

3.session.file.py - хранение сессии в файле
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding: utf-8 -*-
from pprint import pprint
from common import get_session

if '__main__' in __name__:
    """Test if the data is actually persistent across requests"""
    session = get_session(data_dir='./cache', type='file')
    session['Suomi'] = 'Kimi Räikkönen'
    session['Great Britain'] = 'Jenson Button'
    session['Deutchland'] = 'Sebastian Vettel'
    session.save()
    print("Session ID: " + session.id)
    pprint(session)

    session2 = get_session(id=session.id, data_dir='./cache', type='file')

    print
    print("File storage session")
    print("Session ID: " + session2.id)
    pprint(session2)
Результат выполнения программы 3.session.file.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Session ID: 214e9b8724334492a814e5b0b1a797ff
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi Räikkönen',
 '_accessed_time': 1475907695.6439698,
 '_creation_time': 1475907695.6439698}
File storage session
Session ID: 214e9b8724334492a814e5b0b1a797ff
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi Räikkönen',
 '_accessed_time': 1475907695.6447632,
 '_creation_time': 1475907695.6439698}
cache/
├── container_file
│   └── 1
│       └── 18
│           └── 18b9908ab7514d8e8d16ae05e1eb09e0.cache
└── container_file_lock
    └── c
        └── c6
            └── c6e93db703a3eea0207cc7efca5ddd0cbb201919.lock

6 directories, 2 files
Сериализованный кэш в файле 18b9908ab7514d8e8d16ae05e1eb09e0.cache
1
2
3
4
5
Ђ}qXsessionq}q(X_accessed_timeqGAХю%MеќИXSuomiqXKimi RГ¤ikkГ¶nenqX
Great BritainqX
Jenson ButtonqX_creation_timeqGAХю%MеќИX
Deutchlandq	XSebastian Vettelq
us.

Хранение в Memcached

4.session.memcached.py - Хранение сессий в memcached
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# -*- coding: utf-8 -*-
from pprint import pprint
from common import get_session

if '__main__' in __name__:
    """Test if the data is actually persistent across requests"""
    session = get_session(
        type='ext:memcached',
        url='memcached:11211',
    )
    session['Suomi'] = 'Kimi Räikkönen'
    session['Great Britain'] = 'Jenson Button'
    session['Deutchland'] = 'Sebastian Vettel'
    session.save()
    print("Session ID: " + session.id)
    pprint(session)

    session2 = get_session(
        id=session.id,
        type='ext:memcached',
        url='memcached:11211'
    )

    print
    print("Memcached storage session")
    print("Session ID: " + session2.id)
    pprint(session2)
Результат выполнения программы 4.session.memcached.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Session ID: 8c549978a6984a648d2dadba44becd23
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi R\xc3\xa4ikk\xc3\xb6nen',
 '_accessed_time': 1429279819.517085,
 '_creation_time': 1429279819.517085}

Memcached storage session
Session ID: 8c549978a6984a648d2dadba44becd23
{'Deutchland': 'Sebastian Vettel',
 'Great Britain': 'Jenson Button',
 'Suomi': 'Kimi R\xc3\xa4ikk\xc3\xb6nen',
 '_accessed_time': 1429279819.52295,
 '_creation_time': 1429279819.517085}

Хранение в Redis

WSGI-middleware

5.session.wsgi.py - WSGI-meddleware
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from beaker.middleware import SessionMiddleware


def simple_app(environ, start_response):
    # Get the session object from the environ
    session = environ['beaker.session']

    # Set some other session variable
    session['counter'] = session.get('counter', 0) + 1
    session.save()

    start_response('200 OK', [('Content-type', 'text/plain')])
    return [
        str.encode(
            'Counter value is: {}'.format(session['counter'])
        )
    ]

# Configure the SessionMiddleware
session_opts = {
    'session.type': 'file',
    'session.data_dir': './cache2/data',
    'session.lock_dir': './cache2/lock',
    'session.cookie_expires': True,
}
wsgi_app = SessionMiddleware(simple_app, session_opts)


if __name__ == '__main__':
    from paste.httpserver import serve

    serve(wsgi_app, host='0.0.0.0', port=8000)
../../_images/beaker_wsgi_1.png

Первый запуск страницы

../../_images/beaker_wsgi_84.png

На страницу заходили 84 раза

Если хранить кэш на диске, то при значении 13 получим:

$ hexdump -v -C cache2/data/container_file/a/a1/a138e686410c40ef9014549d8b339cc9.cache
00000000  80 03 7d 71 00 58 07 00  00 00 73 65 73 73 69 6f  |..}q.X....sessio|
00000010  6e 71 01 7d 71 02 28 58  07 00 00 00 63 6f 75 6e  |nq.}q.(X....coun|
00000020  74 65 72 71 03 4b 0d 58  0e 00 00 00 5f 61 63 63  |terq.K.X...._acc|
00000030  65 73 73 65 64 5f 74 69  6d 65 71 04 47 41 d5 fe  |essed_timeq.GA..|
00000040  24 8e 01 39 c1 58 0e 00  00 00 5f 63 72 65 61 74  |$..9.X...._creat|
00000050  69 6f 6e 5f 74 69 6d 65  71 05 47 41 d5 fe 24 87  |ion_timeq.GA..$.|
00000060  8d 20 eb 75 73 2e                                 |. .us.|
00000066
Previous: Формы Next: Базы данных