Giter Site home page Giter Site logo

Comments (13)

bradleypeabody avatar bradleypeabody commented on June 28, 2024 1

I think what is happening here is that you have a specific use that works for you, and while I'm sure it's a valid one, it is not necessarily the only way to do it. Your note above implies a separate memcache per-machine - but that is not always the case, in fact it is very common to have a shared memcache on a separate server(s). (And in this case the behavior you describe above is not what happens.)

That said, it does make some sense to perform locking in memcache - I can see that working. This should not be the default behavior though. Doing so would mean that calling store.Get(r, "session-name") would issue a lock (effectively blocking any other access to this session until whatever timeout happens), and yet that is not obvious when you are calling a "Get" method. (Also, "Store" is an interface in Gorilla, http://www.gorillatoolkit.org/pkg/sessions#Store , so you can't really just add a GetReadOnly method)

This is not something I'm able to spend time on, but I'd be willing to merge a pull request that has this implemented as an option that could be turned on, not default.

from gorilla-sessions-memcache.

mevdschee avatar mevdschee commented on June 28, 2024 1

Your note above implies a separate memcache per-machine - but that is not always the case, in fact it is very common to have a shared memcache on a separate server(s). (And in this case the behavior you describe above is not what happens.)

In that case the user won't even notice the fail-over as you don't need sticky sessions at all.

Doing so would mean that calling store.Get(r, "session-name") would issue a lock...

But the problem is that you need to know whether or not the intention is to write to the session or not. If you do an AJAX call that requires login you want a non-blocking read-only session, while a normal "page load" may require adjusting the session data and should thus be locking.

The fact that the Gorilla interface does not facilitate expressing this intention merely explains why this feature is missing from all implementations, but it does not make it right to (strictly) follow that interface (I consider it a design flaw in Gorilla). See also: gorilla/sessions#10

PHP has recently (version 7) added this (read only session) feature, that is so important to achieve both high performance and reliability, see: http://php.net/manual/en/function.session-start.php

from gorilla-sessions-memcache.

mevdschee avatar mevdschee commented on June 28, 2024 1

I like the proposal in the gorilla session issue:

store.Lock(r, "session-name")
defer store.UnLock(r, "session-name")
session, _ := store.Get(r, "session-name")
session.Values["foo"] = "bar"
session.Values[42] = 43    
session.Save(r, w)

and for read-only (no locking):

session, _ := store.Get(r, "session-name")
user := session.Values["user"]

I think that is very simple and allows the user to choose.

from gorilla-sessions-memcache.

bradleypeabody avatar bradleypeabody commented on June 28, 2024 1

I agree, I like it.

from gorilla-sessions-memcache.

bradleypeabody avatar bradleypeabody commented on June 28, 2024

Yes, that's true, but it's also intentional. In an environment with multiple instances of an application, it is not possible to use simple in-memory locking mechanisms to synchronize access (because the instances are on different machines). And a more complex multi-machine locking mechanism more or less defeats the purpose of using a solution as simple as memcache.

But this is usually how memcache-backed applications operate in general. You design the app and the pattern of how it updates memcache with the knowledge that there might be race conditions. It is true that this can be deal-breaker for some applications (I would not be doing payment-related transactions based solely on memcache, for example), but for many it is not.

from gorilla-sessions-memcache.

mevdschee avatar mevdschee commented on June 28, 2024

Okay, well I do build high traffic sites and sticky sessions on your load balancer ensures that you hit the right machine. I suggest the following (where 'Get' acquires the lock and 'Save' releases it):

session, _ := store.Get(r, "session-name")
defer session.Save(r, w)
session.Values["foo"] = "bar"
session.Values[42] = 43    

and for read-only (no locking):

session, _ := store.GetReadOnly(r, "session-name")
user := session.Values["user"]

Calling Save would then fail (because the lock was not acquired). I think that such a setup would avoid race conditions.

from gorilla-sessions-memcache.

bradleypeabody avatar bradleypeabody commented on June 28, 2024

Is that a global lock, one for all sessions? Or a lock for each session?

Right now there is no concept of keeping one of anything per session in memory - this allows the overall memcache size to be completely independent from the memory in each machine. So adding a lock for each session would mean adding a big map with a sync.Mutex for every session.

If you mean a global lock, that's not a good idea because it's serializes all session access and in high traffic environments will kill performance.

As a additional note, sticky sessions do not take into account failover (presumably the reason you have load balancing in the first place), so while it's true that this helps, it doesn't guarantee - you can still have race conditions when machines fail (or even just get slow enough for the load balancer to take a machine out of the cluster).

from gorilla-sessions-memcache.

mevdschee avatar mevdschee commented on June 28, 2024

You should implement a lock per session. The lock can be kept in memcache using the 'add' operation to ensure atomicity on an extra key (with '.lock' suffix).

I wrote this for PHP, see: https://github.com/LeaseWeb/LswMemcacheBundle/blob/master/Session/Storage/LockingSessionHandler.php#L114

I think it should not be too hard to implement.

from gorilla-sessions-memcache.

mevdschee avatar mevdschee commented on June 28, 2024

As for your additional note: sticky sessions may lead to (some) lost sessions on server failure (because the session stickiness is not respected and the other machine's Memcache does not know about the session). This may in practice be acceptable. There are no race conditions, just lost sessions.

from gorilla-sessions-memcache.

bradleypeabody avatar bradleypeabody commented on June 28, 2024

Definitely agreed that the Gorilla interface does not express this difference between read-only Gets and Gets that are followed by a write.

As an idea, maybe explicit methods like GetAndLock and GetNoLock are added to MemcacheStore and then there is an option to indicate which of these is used by Get.

Existing code would run as-is because Get would by default call GetNoLock. With the appropriate option, this could be changed so Get calls GetAndLock, and the caller would have to know what they are doing if they set this option. For more flexibility, the caller could just cast directly to *gsm.MemcacheStore and call whatever methods directly.

from gorilla-sessions-memcache.

mevdschee avatar mevdschee commented on June 28, 2024

Okay, I may need a few days to implement (and test) this. Please have some patience...

from gorilla-sessions-memcache.

bradleypeabody avatar bradleypeabody commented on June 28, 2024

Of course :)

from gorilla-sessions-memcache.

bradleypeabody avatar bradleypeabody commented on June 28, 2024

I'm closing this for now.

from gorilla-sessions-memcache.

Related Issues (2)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.