fixing racing condition like caching issues

21 views
Skip to first unread message

Nicolaas Thiemen Francken

unread,
Dec 11, 2016, 11:54:10 PM12/11/16
to silverstripe-dev
Hi,

I am having a hard time trying to fix racing condition like issues:

  • User presses go.
  • Site does a bunch of stuff (and saves in Database)
  • E-mail is sent to user.
ISSUE
When the email is sent to the user, the data in the e-mail is not what is actually supposed to be in the database by the time the e-mail is sent. 

SOLUTION 1: NOT GOOD
I dont want to use SS_Viewer::flush() to flush the entire cache (this flushes way to much).  

SOLUTION 2: sleep DID NOT WORK
I have tried to use sleep(5) - did not work.  

SOLUTION 3: register_shutdown_function DID NOT WORK
I have also tried to use register_shutdown_function, but also no luck with this method (the concept worked fine, but the e-mail still contained outdated information).

What is the best way forward? Any recommendations?  

Thank you

Nicolaas

Patrick Nelson

unread,
Dec 12, 2016, 12:05:47 AM12/12/16
to silverst...@googlegroups.com
Do you have a code sample that demonstrates the full cycle (particularly to ensure it's reproducible)? It's unclear what could be causing that without a bit more context. i.e. This requires us to know things that we cannot know e.g. what's actually in the email? what is supposed to be in the email vs. what's supposed to be in the database? Was the content in the email the same content that WAS in the database prior to updating (at which point was supposed to be the content that would be in the email)? This could help explain why on earth flushing the cache helps;

My first guess (due to lack of code) is that templates are involved, yes, but may be getting reused within the same request (since template values are idempotent, or, don't change once called). That or maybe you're using <% cached ... %> blocks and need to use a better cache key (or don't do caching at all at this level), etc.

--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to silverstripe-dev+unsubscribe@googlegroups.com.
To post to this group, send email to silverstripe-dev@googlegroups.com.
Visit this group at https://groups.google.com/group/silverstripe-dev.
For more options, visit https://groups.google.com/d/optout.

Sam Minnée

unread,
Dec 12, 2016, 3:02:22 AM12/12/16
to silverst...@googlegroups.com
It's a bit of a sledgehammer to crack a nut, but you could install the queuedjobs module and then do the actual email send from within a queued job. This will mean it is called from a different context.

It would also mean that any execution time for sending the email wouldn't block your website from returning something to the user
On Mon, 12 Dec 2016 at 6:05 PM, Patrick Nelson <p...@catchyour.com> wrote:
Do you have a code sample that demonstrates the full cycle (particularly to ensure it's reproducible)? It's unclear what could be causing that without a bit more context. i.e. This requires us to know things that we cannot know e.g. what's actually in the email? what is supposed to be in the email vs. what's supposed to be in the database? Was the content in the email the same content that WAS in the database prior to updating (at which point was supposed to be the content that would be in the email)? This could help explain why on earth flushing the cache helps;

My first guess (due to lack of code) is that templates are involved, yes, but may be getting reused within the same request (since template values are idempotent, or, don't change once called). That or maybe you're using <% cached ... %> blocks and need to use a better cache key (or don't do caching at all at this level), etc.
On Sun, Dec 11, 2016 at 8:54 PM, Nicolaas Thiemen Francken <nfra...@gmail.com> wrote:
Hi,

I am having a hard time trying to fix racing condition like issues:

  • User presses go.
  • Site does a bunch of stuff (and saves in Database)
  • E-mail is sent to user.
ISSUE
When the email is sent to the user, the data in the e-mail is not what is actually supposed to be in the database by the time the e-mail is sent. 

SOLUTION 1: NOT GOOD
I dont want to use SS_Viewer::flush() to flush the entire cache (this flushes way to much).  

SOLUTION 2: sleep DID NOT WORK
I have tried to use sleep(5) - did not work.  

SOLUTION 3: register_shutdown_function DID NOT WORK
I have also tried to use register_shutdown_function, but also no luck with this method (the concept worked fine, but the e-mail still contained outdated information).

What is the best way forward? Any recommendations?  

Thank you

Nicolaas

--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to silverstripe-d...@googlegroups.com.
To post to this group, send email to silverst...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to silverstripe-d...@googlegroups.com.
To post to this group, send email to silverst...@googlegroups.com.
--

Sam Minnée

CEO

SilverStripe Limited

www.silverstripe.com


Phone: +64 4 978 7334

Twitter: @sminnee


Book a meeting with me


Nicolaas Thiemen Francken

unread,
Dec 12, 2016, 3:53:47 AM12/12/16
to silverstripe-dev
My first guess (due to lack of code) is that templates are involved, yes, but may be getting reused within the same request (since template values are idempotent, or, don't change once called). 

I think that is the issue.  Thank you for your questions and ideas Patrick.  I am experiencing this issue here: https://github.com/sunnysideup/silverstripe-ecommerce/blob/master/code/model/Order.php#L1085-L1104

It would be great if there was a call in SS_Viewer that could make the templates not idempotent (there is SS_Viewer::flush, but that is another sledgehammer). 

@Sam.  Thank you for your reply.   What you basically confirm to me is: this error is possible and there is no quick solution to fix it.  Thus, what I will do is to create a new table with:

OrderID, NOW, NeedsAttentionXSecondsInTheFuture

A cronjob will then go through this list every fives minutes or so to see if there are any Orders that need to progress. 

I also wonder if I could simply run the emailing bit from sake during the processing. Could you use: "shell_exec"?  Sounds dodgy, but could be effective. 

I have worked with queuedjobs before, but, as you say, that may be overkill. 

I like what you are saying about avoiding the delay while sending mail (although I have not experienced it). 

Is it worth raising an issue on github for the creation of a SS_Viewer::reset_data_in_templates() method? How do templates become idempotent in the first place?

Thank you again for your replies.

Nicolaas


off...@netwerkstatt.at

unread,
Dec 12, 2016, 2:00:33 PM12/12/16
to silverst...@googlegroups.com

Educated guess: you don’t reload data from DB before you pass it to the mail? Sometimes when writing to DB not all changes are reflected in the current object, so in doubt re-fetch the data.

--

Sam Minnée

unread,
Dec 12, 2016, 2:22:01 PM12/12/16
to silverst...@googlegroups.com
Nicolaas, you've just suggested that your own hand rolled version of queuedjobs. It would probably be better to use queuedjobs?

--
You received this message because you are subscribed to the Google Groups "SilverStripe Core Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to silverstripe-d...@googlegroups.com.
To post to this group, send email to silverst...@googlegroups.com.
Visit this group at https://groups.google.com/group/silverstripe-dev.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages