简体   繁体   中英

Loop in Ruby on Rails running twice

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)

Was going to write comment, but it will be clearer here:

I'd imagine there to be 3 potential causes of your problem:

  1. Perhaps update is saving the data incorrectly / before & after the webservice call
  2. Your webservice may be taking too long
  3. Perhaps something else is messing-up?

update_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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM