Reputation: 2718
I'm going crazy. My each-loop in rails always runs twice for each collection item. I have no clue why.
locations = Location.all
locations.each do |loc|
# delay to not overload le webservice
sleep 1.0
if [... some webservice call - runs fine ... ]
# score calculation - V0.1
score = [... some formula to calculate a score ...]
score_total = score + loc.score_total
score_count = loc.score_count + 1
# update the current record which fresh values from the webservice
loc.update(:temp1 => temp[0],
:temp2 => temp[1],
:temp3 => temp[2],
:temp4 => temp[3],
:temp5 => temp[4],
:condition1 => condition[0],
:condition2 => condition[1],
:condition3 => condition[2],
:condition4 => condition[3],
:condition5 => condition[4],
:score_yesterday => loc.score_now,
:score_now => score,
:score_total => score_total,
:score_count => score_count)
end
end
count jumps in 2-times steps
some variables I want to update within each iteration are always behind
LOG:
Started GET "/loc" for 127.0.0.1 at 2014-02-01 13:37:22 +0100
Processing by WhitelabelsController#loc as HTML
[1m[36mWhitelabelWsd Load (0.6ms)[0m [1mSELECT "whitelabel_wsds".* FROM "whitelabel_wsds"[0m
[1m[35m (0.3ms)[0m BEGIN
[1m[36mSQL (4.4ms)[0m [1mUPDATE "whitelabel_wsds" SET "temp1" = $1, "temp2" = $2, "temp3" = $3, "temp4" = $4, "temp5" = $5, "condition1" = $6, "condition2" = $7, "condition3" = $8, "condition4" = $9, "condition5" = $10, "score_now" = $11, "score_total" = $12, "score_count" = $13, "updated_at" = $14 WHERE "whitelabel_wsds"."id" = 2[0m [["temp1", 17], ["temp2", 15], ["temp3", 13], ["temp4", 14], ["temp5", 13], ["condition1", "Patchy rain nearby"], ["condition2", "Cloudy "], ["condition3", "Sunny"], ["condition4", "Light rain shower"], ["condition5", "Sunny"], ["score_now", 306], ["score_total", 10934], ["score_count", 48], ["updated_at", Sat, 01 Feb 2014 12:37:23 UTC +00:00]]
[1m[35m (264.2ms)[0m COMMIT
[1m[36m (0.2ms)[0m [1mBEGIN[0m
[1m[35mSQL (0.8ms)[0m UPDATE "whitelabel_wsds" SET "temp1" = $1, "temp2" = $2, "temp3" = $3, "temp4" = $4, "temp5" = $5, "condition1" = $6, "condition2" = $7, "condition3" = $8, "condition4" = $9, "condition5" = $10, "score_now" = $11, "score_total" = $12, "score_count" = $13, "updated_at" = $14 WHERE "whitelabel_wsds"."id" = 3 [["temp1", 16], ["temp2", 11], ["temp3", 16], ["temp4", 13], ["temp5", 17], ["condition1", "Cloudy "], ["condition2", "Sunny"], ["condition3", "Cloudy "], ["condition4", "Sunny"], ["condition5", "Partly Cloudy "], ["score_now", 391], ["score_total", 22791], ["score_count", 51], ["updated_at", Sat, 01 Feb 2014 12:37:25 UTC +00:00]]
[1m[36m (1.3ms)[0m [1mCOMMIT[0m
[1m[35m (0.1ms)[0m BEGIN
[1m[36mSQL (1.4ms)[0m [1mUPDATE "whitelabel_wsds" SET "temp1" = $1, "temp2" = $2, "temp3" = $3, "temp4" = $4, "temp5" = $5, "condition1" = $6, "condition2" = $7, "score_now" = $8, "score_total" = $9, "score_count" = $10, "updated_at" = $11 WHERE "whitelabel_wsds"."id" = 1[0m [["temp1", 21], ["temp2", 22], ["temp3", 21], ["temp4", 22], ["temp5", 23], ["condition1", "Partly Cloudy "], ["condition2", "Partly Cloudy "], ["score_now", 961], ["score_total", 93375], ["score_count", 61], ["updated_at", Sat, 01 Feb 2014 12:37:26 UTC +00:00]]
[1m[35m (0.5ms)[0m COMMIT
Rendered whitelabels/loc.html.erb within layouts/whitelabel (0.1ms)
Completed 200 OK in 4318ms (Views: 6.6ms | ActiveRecord: 277.8ms)
Started GET "/loc" for 127.0.0.1 at 2014-02-01 13:37:26 +0100
Processing by WhitelabelsController#loc as HTML
[1m[36mWhitelabelWsd Load (0.7ms)[0m [1mSELECT "whitelabel_wsds".* FROM "whitelabel_wsds"[0m
[1m[35m (0.2ms)[0m BEGIN
[1m[36mSQL (0.7ms)[0m [1mUPDATE "whitelabel_wsds" SET "score_yesterday" = $1, "score_total" = $2, "score_count" = $3, "updated_at" = $4 WHERE "whitelabel_wsds"."id" = 2[0m [["score_yesterday", 306], ["score_total", 11240], ["score_count", 49], ["updated_at", Sat, 01 Feb 2014 12:37:27 UTC +00:00]]
[1m[35m (0.6ms)[0m COMMIT
[1m[36m (0.2ms)[0m [1mBEGIN[0m
[1m[35mSQL (0.6ms)[0m UPDATE "whitelabel_wsds" SET "score_yesterday" = $1, "score_total" = $2, "score_count" = $3, "updated_at" = $4 WHERE "whitelabel_wsds"."id" = 3 [["score_yesterday", 391], ["score_total", 23182], ["score_count", 52], ["updated_at", Sat, 01 Feb 2014 12:37:29 UTC +00:00]]
[1m[36m (0.5ms)[0m [1mCOMMIT[0m
[1m[35m (0.2ms)[0m BEGIN
[1m[36mSQL (0.5ms)[0m [1mUPDATE "whitelabel_wsds" SET "score_yesterday" = $1, "score_total" = $2, "score_count" = $3, "updated_at" = $4 WHERE "whitelabel_wsds"."id" = 1[0m [["score_yesterday", 961], ["score_total", 94336], ["score_count", 62], ["updated_at", Sat, 01 Feb 2014 12:37:30 UTC +00:00]]
[1m[35m (0.5ms)[0m COMMIT
Rendered whitelabels/loc.html.erb within layouts/whitelabel (0.1ms)
Completed 200 OK in 3598ms (Views: 4.7ms | ActiveRecord: 4.5ms)
Upvotes: 0
Views: 1339
Reputation: 2718
I have solved it while implementing two different functions:
def check_weather(location_station)
[... webservice call ... ]
end
locations.each do |loc|
sleep 1.0
check_weather(loc.location_station)
loc.update(...)
end
Upvotes: 0
Reputation: 76774
Was going to write comment, but it will be clearer here:
I'd imagine there to be 3 potential causes of your problem:
update
is saving the data incorrectly / before & after the webservice callupdate_attributes
Having looked over the .update
& .update_attributes
methods, it looks like you could replace .update
with .update_attributes
Although the difference escapes me, we use update_attributes
all the time - it does exactly what you need here:
loc.update_attributes(
:temp1 => temp[0],
:temp2 => temp[1],
:temp3 => temp[2],
:temp4 => temp[3],
:temp5 => temp[4],
:condition1 => condition[0],
:condition2 => condition[1],
:condition3 => condition[2],
:condition4 => condition[3],
:condition5 => condition[4],
:score_yesterday => loc.score_now,
:score_now => score,
:score_total => score_total,
:score_count => score_count
)
Webservice
Another issue may be that your webservice call is taking too long
Any external dependencies obviously carry added latency, which you may need to factor into your process
Currently, you don't have any logic to determine whether the call was successful or not. This could explain your app's increasing the count without the other items (it doesn't have access to the new data):
locations.each do |loc|
if [... some webservice call - runs fine ... ]
# score calculation - V0.1
score = [... some formula to calculate a score ...]
score_total = score + loc.score_total
# update the current record which fresh values from the webservice
loc.update_attributes(:temp1 => temp[0],
:temp2 => temp[1],
:temp3 => temp[2],
:temp4 => temp[3],
:temp5 => temp[4],
:condition1 => condition[0],
:condition2 => condition[1],
:condition3 => condition[2],
:condition4 => condition[3],
:condition5 => condition[4],
:score_yesterday => loc.score_now,
:score_now => score,
:score_total => score_total
)
loc.increment!(:score_count)
end
end
.increment!
method ;)
Logs
Lots of these types of error can be explained with the logs
The logs will detail exactly which calls are being made & when; allowing us to see what's happening
Upvotes: 1