From 012363fca2bbe2d75145e8ca3b85f8fcb48ad164 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Mar 2018 12:16:50 +0100 Subject: Route: Get rid of unnecessary whitespace Refs #6095 --- app/models/chouette/route.rb | 1 - 1 file changed, 1 deletion(-) (limited to 'app') diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 26b80733d..d0d776bc6 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -1,4 +1,3 @@ - module Chouette class Route < Chouette::TridentActiveRecord has_paper_trail -- cgit v1.2.3 From dbcd099b3d38f7c584450edffc8bee0a2502b170 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Mar 2018 15:37:55 +0100 Subject: Route: Add `#calculate_costs!` to populate `#costs` with `WayCost`s This new method will launch a worker that takes the route's `StopArea`s, converts them to `WayCost`s, sends them to the TomTom API to calculate distance and time costs, and saves those costs to the route's `costs` field. Refs #6095 --- app/models/chouette/route.rb | 4 ++++ app/services/route_way_cost_calculator.rb | 12 ++++++++++++ app/workers/route_way_cost_worker.rb | 8 ++++++++ 3 files changed, 24 insertions(+) create mode 100644 app/services/route_way_cost_calculator.rb create mode 100644 app/workers/route_way_cost_worker.rb (limited to 'app') diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index d0d776bc6..a1d44f53f 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -188,6 +188,10 @@ module Chouette journey_pattern end + def calculate_costs! + RouteWayCostWorker.perform_async(id) + end + protected def self.vehicle_journeys_timeless(stop_point_id) diff --git a/app/services/route_way_cost_calculator.rb b/app/services/route_way_cost_calculator.rb new file mode 100644 index 000000000..2e30c94fc --- /dev/null +++ b/app/services/route_way_cost_calculator.rb @@ -0,0 +1,12 @@ +class RouteWayCostCalculator + def initialize(route) + @route = route + end + + def calculate! + way_costs = StopAreasToWayCostsConverter.new(@route.stop_areas).convert + way_costs = TomTom.batch(way_costs) + way_costs = WayCostCollectionJSONSerializer.dump(way_costs) + @route.update(costs: way_costs) + end +end diff --git a/app/workers/route_way_cost_worker.rb b/app/workers/route_way_cost_worker.rb new file mode 100644 index 000000000..adb10957b --- /dev/null +++ b/app/workers/route_way_cost_worker.rb @@ -0,0 +1,8 @@ +class RouteWayCostWorker + include Sidekiq::Worker + + def perform(route_id) + route = Chouette::Route.find(route_id) + RouteWayCostCalculator.new(route).calculate! + end +end -- cgit v1.2.3 From cbb6831b64b0474d5798820c20bdc0f958bd795d Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Mar 2018 15:48:17 +0100 Subject: Route: Fix whitespace This method wasn't indented to the same level as the rest of the file. Refs #6095 --- app/models/chouette/route.rb | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'app') diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index a1d44f53f..ddc4aece6 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -75,19 +75,19 @@ module Chouette validates :wayback, inclusion: { in: self.wayback.values } - def duplicate - overrides = { - 'opposite_route_id' => nil, - 'name' => I18n.t('activerecord.copy', name: self.name) - } - keys_for_create = attributes.keys - %w{id objectid created_at updated_at} - atts_for_create = attributes - .slice(*keys_for_create) - .merge(overrides) - new_route = self.class.create!(atts_for_create) - duplicate_stop_points(for_route: new_route) - new_route - end + def duplicate + overrides = { + 'opposite_route_id' => nil, + 'name' => I18n.t('activerecord.copy', name: self.name) + } + keys_for_create = attributes.keys - %w{id objectid created_at updated_at} + atts_for_create = attributes + .slice(*keys_for_create) + .merge(overrides) + new_route = self.class.create!(atts_for_create) + duplicate_stop_points(for_route: new_route) + new_route + end def duplicate_stop_points(for_route:) stop_points.each(&duplicate_stop_point(for_route: for_route)) -- cgit v1.2.3 From 1ce665267da0e303661e28b8f228ccac3823fa36 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Mar 2018 16:38:12 +0100 Subject: Route: Run `#calculate_costs!` on `after_save` Not efficient to send a request to the TomTom API every time we save a Route, but I'm banking on developing a cache system soon to avoid having to make the requests, so hopefully that will stop this from making expensive remote calls all the time. Refs #6095 --- app/models/chouette/route.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app') diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index ddc4aece6..f0fe06a58 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -75,6 +75,8 @@ module Chouette validates :wayback, inclusion: { in: self.wayback.values } + after_save :calculate_costs! + def duplicate overrides = { 'opposite_route_id' => nil, -- cgit v1.2.3 From 3fe9aad1d003814c2f5a5de834ce42a028df1753 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Mar 2018 18:08:16 +0100 Subject: RouteWayCostWorker: Switch to referential in order to find Route Just running `Chouette::Route.find(id)` doesn't give us anything if we don't have a `Referential` selected. In order to properly get the correct route, pass the referential ID to the worker and switch to that referential before trying to select the route. Refs #6095 --- app/models/chouette/route.rb | 2 +- app/workers/route_way_cost_worker.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index f0fe06a58..01358e8aa 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -191,7 +191,7 @@ module Chouette end def calculate_costs! - RouteWayCostWorker.perform_async(id) + RouteWayCostWorker.perform_async(referential.id, id) end protected diff --git a/app/workers/route_way_cost_worker.rb b/app/workers/route_way_cost_worker.rb index adb10957b..fa5bd737d 100644 --- a/app/workers/route_way_cost_worker.rb +++ b/app/workers/route_way_cost_worker.rb @@ -1,7 +1,8 @@ class RouteWayCostWorker include Sidekiq::Worker - def perform(route_id) + def perform(referential_id, route_id) + Referential.find(referential_id).switch route = Chouette::Route.find(route_id) RouteWayCostCalculator.new(route).calculate! end -- cgit v1.2.3 From 13135a5251f2af3e85bb2bb1be9866477b7414e9 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Mar 2018 18:10:46 +0100 Subject: RouteWayCostWorker: Fix recursive worker call Since this method was run on `after_save` and in it `RouteWayCostCalculator` calls `#update` on the given route, it caused an infinite recursive call to the worker. To prevent this, wrap the `#calculate!` call in methods that unset and reset the callback. Refs #6095 --- app/workers/route_way_cost_worker.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'app') diff --git a/app/workers/route_way_cost_worker.rb b/app/workers/route_way_cost_worker.rb index fa5bd737d..2ec8cdff9 100644 --- a/app/workers/route_way_cost_worker.rb +++ b/app/workers/route_way_cost_worker.rb @@ -4,6 +4,11 @@ class RouteWayCostWorker def perform(referential_id, route_id) Referential.find(referential_id).switch route = Chouette::Route.find(route_id) + + Chouette::Route.skip_callback(:save, :after, :calculate_costs!) + RouteWayCostCalculator.new(route).calculate! + + Chouette::Route.set_callback(:save, :after, :calculate_costs!) end end -- cgit v1.2.3 From a5d070093a2561c4924a030338db9064cdff7a16 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Tue, 13 Mar 2018 18:45:28 +0100 Subject: RouteWayCostWorker: Add comment about recursive workers Explain why we need to skip and un-skip the callback. Refs #6095 --- app/workers/route_way_cost_worker.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app') diff --git a/app/workers/route_way_cost_worker.rb b/app/workers/route_way_cost_worker.rb index 2ec8cdff9..d6bfed592 100644 --- a/app/workers/route_way_cost_worker.rb +++ b/app/workers/route_way_cost_worker.rb @@ -5,6 +5,8 @@ class RouteWayCostWorker Referential.find(referential_id).switch route = Chouette::Route.find(route_id) + # Prevent recursive worker spawning since this call updates the + # `costs` field of the route. Chouette::Route.skip_callback(:save, :after, :calculate_costs!) RouteWayCostCalculator.new(route).calculate! -- cgit v1.2.3 From 9dc7c942fd7e0c0b298bfff08088c830841f666c Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Wed, 14 Mar 2018 11:02:42 +0100 Subject: Route#duplicate: Use `#slice!` instead of `#slice` Johan suggested simplifying this method by changing the `slice` call: http://api.rubyonrails.org/classes/Hash.html#method-i-slice-21 I had modified this to fix the whitespace while working on the `WayCost` calculation function for `Chouette::Route`s, so don't really have a brain cache hit on this code, but the change makes sense and seems to work. Refs #6095 --- app/models/chouette/route.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'app') diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 01358e8aa..4b1b88543 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -82,9 +82,8 @@ module Chouette 'opposite_route_id' => nil, 'name' => I18n.t('activerecord.copy', name: self.name) } - keys_for_create = attributes.keys - %w{id objectid created_at updated_at} atts_for_create = attributes - .slice(*keys_for_create) + .slice!(*%w{id objectid created_at updated_at}) .merge(overrides) new_route = self.class.create!(atts_for_create) duplicate_stop_points(for_route: new_route) -- cgit v1.2.3 From 9291d45e825edbaf52cb556c102498366985496f Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Thu, 15 Mar 2018 11:52:16 +0100 Subject: Route: Don't run `#calculate_costs!` on callback if TomTom disabled We say `TomTom` is disabled when no API key is present. If this is the case, the `after_save` callback that uses it shouldn't be executed. I had to change my `API_KEY` constant to an instance variable to be able to change it for testing. Refs #6095 --- app/models/chouette/route.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app') diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 4b1b88543..f814d5160 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -75,7 +75,7 @@ module Chouette validates :wayback, inclusion: { in: self.wayback.values } - after_save :calculate_costs! + after_save :calculate_costs!, if: ->() { TomTom.enabled? } def duplicate overrides = { -- cgit v1.2.3