On Sun, 2011-05-08 at 09:55 +1000, Tacit Sawk wrote:
> > newtype HitCounterState = HitCounterState
> > { _hits :: Int
> > }
>
Since this is shared state between requests, you want an MVar here to
coordinate updates. i.e.,
newType HitCounterState = HitCounterState { _hits :: MVar Int }
> > hitCounterInitializer :: Int -> Initializer HitCounterState
> > hitCounterInitializer n = return n >>= mkInitializer . HitCounterState
And here, 'return n' becomes 'newMVar n'
> And likewise for MonadHitCounter (ReaderT s m). The issue is in an
> attempt at incrementHits:
>
> > incrementHits = do
> > hits <- getHits
> > tell setHitCounterState { _hits=hits }
So here you'll want modifyMVar.
> Even this is clunky and possibly wrong, but I can't use trial and error
> to discover the best way to lay this out, because (of course) MonadSnap
> doesn't include MonadWriter or a StateT or ... well, whatever.
In general, you don't want a WriterT or StateT. They operate on state
(or accumulated results) that is local to a single thread of execution;
shared state, like your hit counter that needs to be updated by multiple
threads, doesn't fit into that model at all. MVar is the right answer
here.
By the way, keep in mind that the Snap extensions API is experimental,
and very likely to change (and hopefully become much simpler, as well as
more functional) in the future.
--
Chris Smith
_______________________________________________
Snap mailing list
[email protected]
http://mailman-mail5.webfaction.com/listinfo/snap