Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sessions support #3

Open
hartror opened this issue May 5, 2017 · 2 comments
Open

Sessions support #3

hartror opened this issue May 5, 2017 · 2 comments

Comments

@hartror
Copy link

hartror commented May 5, 2017

A common usage of dogpile.cache like its predecessor beaker is to store session information such as with the pyramid_beaker library. What are thoughts on having a similar implementation for pyramid_dogpile_cache2?

Thanks

@wosc
Copy link
Member

wosc commented May 5, 2017

In one of our projects we indeed use a pyramid session implementation that uses a dogpile.cache region to store the information. Unfortunately, the pyramid session code is not factored very friendly for extending, so this involved quite a bit of copy&paste. The basic idea looked something like below, but note, that's not fully working code, just a rough draft of the main structure. I'm definitely open to a pull request if you want to flesh this out, but I won't have time to work on this myself.

SESSION_CACHE = pyramid_dogpile_cache2.get_region('session')

@zope.interface.implementer(pyramid.interfaces.ISession)
class CacheSession(dict):

    def __init__(self, request):
        self.request = request

        stored = SESSION_CACHE.get(
            self.session_id) if self.session_id else NO_VALUE
        if stored is not NO_VALUE:
            super(CacheSession, self).__init__(stored)
        else:
            now = int(time.time())
            self.created = now
            self.accessed = now
            self.renewed = now

    @property
    def session_id(self):
        return self.request.cookies.get('my_session_cookie')

    def persist(self):
        if not self.session_id:
            return
        SESSION_CACHE.set(self.session_id, dict(self))

    def changed(self):
        if not self._dirty:
            self._dirty = True
            self.renewed = time_now()

            def store_session(request, response):
                self.persist()
                self._set_cookie(response)
                self.request = None  # explicitly break cycle for GC
            self.request.add_response_callback(store_session)

# in your pyramid setup
config.set_session_factory(CacheSession)

@hartror
Copy link
Author

hartror commented May 6, 2017

Thanks @wosc I am indeed happy to have a crack at a PR in the near future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants