Rotating quicker than it should be

martinjbaker - April 17, 2009 - 21:37
Project:Slot Machine
Version:6.x-1.0-beta2
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:closed
Description

I'm having some problems with Slot Machine rotating content faster than it says it is scheduled and am not sure how to rectify it.

I set up 2 frequencies - "hourly" and "daily at 12". I used the hourly one for testing and all seemed to work fine. So then I changed it to "daily at 12" and placed some nodes in the queue. Cron is running every 15 mins and what seemed to be happening is that rather than respecting the scheduled time, it would rotate to the next queued content on every cron run rather than waiting for the scheduled time.

For 2 or 3 days I had nothing else in the queue and I'm wondering whether Slot Machine thinks that it needs to somehow "catch up" with the missed schedules so is rotating content at every possible opportunity. If this is the case, is there any way to start again because it seems to be a tricky one to get out of.

thanks

#1

mcarbone - April 17, 2009 - 21:53

Hmm, hard to tell from that description, but there could be something up with missed schedules. Can you post a screenshot of the slot machine schedule page, and if you can the contents of the slot_machine table?

#2

martinjbaker - April 20, 2009 - 22:42

Thanks for reply. I've done some digging in the slot_machine_history table and put the GMT times alongside (slot_history.gif). If you compare this with the grab of the schedule on Friday 17th (slot_schedule_friday.png) you can see that the next item has a scheduled time of the day before the current time (which seems odd in itself).

According to the history what happened, was that the hmcknight item went live at 1345 and on the next 15 min cron, at 1400, the pxdfilms item went live. At 1415 a third item went live (added to the schedule after the grab was taken) and then I checked the site and saw it was going wrong so re-scheduled the hmcknight item which went live at 1431. The final item on the history was nid 432 manually scheduled. Ever since then i've been manually scheduling a single new item and it goes live on the next cron.

hope that makes sense!

AttachmentSize
slot_schedule_friday.png 133 KB
slot_history.gif 53.43 KB
slot_schedule_current.png 62.43 KB
slot_table.png 39.7 KB

#3

mcarbone - April 21, 2009 - 00:32

Thanks, that should be helpful. I'll take a look within a day or two.

#4

mcarbone - April 21, 2009 - 23:48

OK, I spent some time digging into this -- reading through the rotation code always requires time and concentration as it's doing some complex stuff.

In any case, here's how it works: when cron runs, it looks at when the current item in the schedule went live, and if it is expired, it will remove it immediately. So that's why it can show a time earlier in the day -- because the item currently in the slot went live before noon, so the next cron run will replace it immediately with the next item in the queue. Note: those "scheduled" times in the queue are only estimates, and depend on when cron runs -- they are not actually used when cron runs. Instead, cron just rotates the next thing in if the current item is expired.

However, after that it should stop -- it should see that the next item went live after noon, and so nothing should go live until after noon the next day.

So the question is, why does it keep going on your server and not mine?

I'm not entirely sure yet, but I did realize one problem while digging -- slot machine uses the database server's timezone to determine when something should rotate. So if your db server is on EST time and your site PST, a slot set to "daily at 12" will rotate at 12 noon EST, not 12 noon PST. This is bad I think, and so I've created another issue to fix this problem: #441010: Slot Machine should use Drupal's timezone instead of MySQL's UNIX_TIMESTAMP()

But this shouldn't be causing your problem, since it's consistently using your db server's time, even if it is different. To show you what I mean, I'll display a little code. Here's is the query that decides whether or not a slot with a daily frequency should be replaced or not during cron:

(sm.schedule < UNIX_TIMESTAMP(CONCAT(DATE(now()), ' ', f.start))
                                     AND UNIX_TIMESTAMP(now()) > UNIX_TIMESTAMP(CONCAT(DATE(now()), ' ', f.start)))

This says, assuming f.start is 12 noon: "Check if the time it went live (sm.schedule) is less than 12 noon today and if right now it's past 12 noon today." If this is true, then it replaces that slot in the schedule with the next item in the queue, if there is one. When it puts in the new item, it sets the schedule for that item:

SET ... schedule = UNIX_TIMESTAMP(now())

It seems like it would be impossible for the new schedule to be less than the expiration time the second time around, let alone the third and fourth, unless I'm not fully appreciating how screwy things could get using the db server's timezone if it's very different. (But it seems to me that it shouldn't be a relative problem, just an absolute problem.)

So, I'm still not sure why you are having this problem. A few more questions:

1) Can you find out if your db server's time zone is different than your site? You can check by doing:

SELECT NOW();

If so, let me know the differential.

2) If possible, can you try again to let this run automatically with daily at 12 noon turned on and items in the queue? And if it is still replacing it with every cron run (which to speed things up you can probably run manually), can you take a snapshot of the slot_machine table between each cron run?

If you want to help debug, you could also run that query above right before the cron run and figure out why it's true:

SELECT (sm.schedule < UNIX_TIMESTAMP(CONCAT(DATE(now()), ' ', '12:00'))
                                     AND UNIX_TIMESTAMP(now()) > UNIX_TIMESTAMP(CONCAT(DATE(now()), ' ', '12:00')))

Using the schedule field from the first row of the slot_machine table as sm.schedule. The question is why that is repeatedly true when schedule becomes UNIX_TIMESTAMP(now()) after each cron run.

Sorry I'm still not sure the exact problem you're having, although it's possible fixing #441010: Slot Machine should use Drupal's timezone instead of MySQL's UNIX_TIMESTAMP() could make it go away, or at least make it easier to debug.

#5

martinjbaker - April 22, 2009 - 20:53

Thanks Marco.

1) The time is the same - both are on the same server.

I think as it turns out, I'm going to have to start over and look for another solution probably based around Nodequeue. Not because of this issue but the number of actions that need to happen at the publishing time are more than originally thought. However once we have another solution in place on the live site I'll be happy to run the other tests and I will also have some UI feedback.

#6

mcarbone - April 22, 2009 - 21:30
Status:active» postponed (maintainer needs more info)

Sounds good. Adding a "Live on schedule" trigger wouldn't be that hard to do, so I should consider that.

In the meantime, I'll set this to needs more info until I can get enough info to recreate this or debug on someone else's site.

#7

martinjbaker - May 4, 2009 - 23:02

OK we've now got our nodequeue solution up and running so I could run some tests. I added 3 nodes to the schedule and as before on every 15 min cron run it rotated to the next item. Here are various table dumps with context around them.

Generation Time: May 04, 2009 at 09:41 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine` LIMIT 0, 30 ;
Rows: 1
nid topic feature_type priority schedule
453 7 rigimage 0 1241093717


*****************************
ADDED 3 NODES TO THE SCHEDULE
*****************************


Generation Time: May 04, 2009 at 09:47 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine` LIMIT 0, 30 ;
Rows: 4
nid topic feature_type priority schedule
476 7 rigimage 1 1241179200
496 7 rigimage 2 1241265600
595 7 rigimage 3 1241352000
453 7 rigimage 0 1241093717


*****************************
ROTATED TO NEXT ITEM AT 2200hrs
*****************************


Generation Time: May 04, 2009 at 10:01 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine` LIMIT 0, 30 ;
Rows: 3
nid topic feature_type priority schedule
476 7 rigimage 0 1241474402
496 7 rigimage 1 1241524800
595 7 rigimage 2 1241611200


Generation Time: May 04, 2009 at 10:04 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine_frequencies` LIMIT 0, 30 ;
Rows: 2
fid name frequency start
1 Never NULL NULL
2 Daily at 1200 0 12:00


Generation Time: May 04, 2009 at 10:04 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine_slots_frequencies` LIMIT 0, 30 ;
Rows: 2
sid topic fid
1 0 1
1 7 2


*****************************
ROTATED TO NEXT ITEM AT 2215hrs
*****************************


Generation Time: May 04, 2009 at 10:15 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine` LIMIT 0, 30 ;
Rows: 2
nid topic feature_type priority schedule
496 7 rigimage 0 1241475303
595 7 rigimage 1 1241524800


*****************************
ROTATED TO NEXT ITEM AT 2230hrs
*****************************


Generation Time: May 04, 2009 at 10:30 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine` LIMIT 0, 30 ;
Rows: 1
nid topic feature_type priority schedule
595 7 rigimage 0 1241476202


*****************************
ROTATED TO NEXT ITEM AT 2245hrs
*****************************


Generation Time: May 04, 2009 at 10:45 PM
Generated by: phpMyAdmin 2.11.9.4 / MySQL 4.1.22-standard
SQL query: SELECT * FROM `slot_machine` LIMIT 0, 30 ;
Rows: 1
nid topic feature_type priority schedule
442 7 rigimage 0 1241477103

After the first rotate, I ran your query in phpMyAdmin and it returned "0" which I think is what's expected. Then looked at the code in slot_machine.module. Was a bit puzzled by the code before the query you quoted.

WHERE f.name != 'Never' //true - it is "12:00"
AND (UNIX_TIMESTAMP(now()) > sm.schedule + f.frequency - 120 //time now will always be greater than the previous time minus 120
OR (sm.schedule < UNIX_TIMESTAMP(CONCAT(DATE(now()), ' ', f.start))
AND UNIX_TIMESTAMP(now()) > UNIX_TIMESTAMP(CONCAT(DATE(now()), ' ', f.start))))

The frequency is set to "0" so wouldn't that first timestamp condition always return true making the second and third ones superfluous? Or am I misunderstanding?

thanks

Martin

#8

mcarbone - May 5, 2009 - 17:37

The frequency is set to "0" so wouldn't that first timestamp condition always return true making the second and third ones superfluous? Or am I misunderstanding?

No, that's exactly the problem! And it explains why I wasn't able to recreate. The question is: why is the frequency set to 0 for you? Here is the query that inserts the daily frequency:

INSERT INTO {slot_machine_frequencies} (name, frequency, start) VALUES ("%s", NULL, "%s")

So it looks like that for some reason, your mysql is inserting 0 instead of NULL. That query would fail if it was NULL, but not with 0. Seems to me that I should make that query more reliable somehow, but in any case -- why do you think you are getting a 0 for that field? I didn't realize there were consistency problems using NULL.

#9

martinjbaker - May 5, 2009 - 17:46

My knowledge of PHP/mysql is very basic, so I don't have an answer for that, sorry! What I am wondering though is my memory is correct and whether I was actually using a single frequency all along. So perhaps I set up the frequency as "every hour" for testing (which worked fine) then edited the same frequency to make it "1200 daily". Might be worth a look.

Martin

#10

mcarbone - May 5, 2009 - 18:33
Status:postponed (maintainer needs more info)» fixed

Yep, that's where the problem was, in updating frequencies. It wasn't reliably using NULL where it should have been. The fix has been committed. Thanks for all the help, Martin!

#11

System Message - May 19, 2009 - 18:40
Status:fixed» closed

Automatically closed -- issue fixed for 2 weeks with no activity.

 
 

Drupal is a registered trademark of Dries Buytaert.