caddie 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/models/caddie/crest_data_retriever.rb +1 -1
  3. data/app/models/caddie/crest_price_history_update.rb +11 -3
  4. data/app/models/caddie/m_threaded_updater.rb +38 -1
  5. data/app/models/crest_price_history.rb +4 -0
  6. data/db/migrate/20160725091214_add_indexes_to_crest_price_history_update.rb +8 -0
  7. data/lib/caddie/version.rb +1 -1
  8. data/lib/tasks/caddie_tasks.rake +8 -3
  9. data/lib/tasks/m_threaded_updater_test.rake +53 -0
  10. data/test/dummy/app/models/eve_item.rb +53 -0
  11. data/test/dummy/app/models/region.rb +4 -0
  12. data/test/dummy/config/database.yml +3 -3
  13. data/test/dummy/db/migrate/20150410082132_create_eve_items.rb +11 -0
  14. data/test/dummy/db/migrate/20150414095303_add_name_lowcase_to_eve_item.rb +5 -0
  15. data/test/dummy/db/migrate/20150416154256_rename_eve_item_id.rb +5 -0
  16. data/test/dummy/db/migrate/20150417135716_add_cost_to_eve_item.rb +5 -0
  17. data/test/dummy/db/migrate/20150906171550_add_cpp_market_group_id_to_eve_item.rb +6 -0
  18. data/test/dummy/db/migrate/20150909162142_add_involved_in_blueprint_to_eve_item.rb +5 -0
  19. data/test/dummy/db/migrate/20150910074544_create_regions.rb +11 -0
  20. data/test/dummy/db/migrate/20150910080646_create_crest_price_histories.rb +18 -0
  21. data/test/dummy/db/schema.rb +19 -299
  22. data/test/dummy/log/development.log +446 -54107
  23. data/test/dummy/log/test.log +46048 -0
  24. data/test/factories/caddie/crest_price_history_updates.rb +4 -0
  25. data/test/factories/caddie/eve_items.rb +54 -0
  26. data/test/factories/caddie/regions.rb +33 -0
  27. data/test/models/caddie/crest_price_history_update_test.rb +19 -4
  28. data/test/models/caddie/m_threaded_updater_test.rb +26 -0
  29. data/test/test_helper.rb +10 -0
  30. metadata +72 -30
  31. data/app/models/crest_price_history.rb +0 -1
  32. data/app/models/eve_item.rb +0 -1
  33. data/app/models/region.rb +0 -1
  34. data/test/fixtures/caddie/crest_price_history_update_logs.yml +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ae68e873fe5e7e634110966042264a149da5f8b
4
- data.tar.gz: 18100d92938dc47517cbcb0b058c4b309e2cbe96
3
+ metadata.gz: dec5dc1e0bf8562abd8ce5afcbefcb44ef4d0f4c
4
+ data.tar.gz: b27051154d8eb7d652ad9dc79b0f91397ca6fc75
5
5
  SHA512:
6
- metadata.gz: f7a9babedd01608b5b19751525e57fe7127e056b7410df5c130d783c41cd3e6c9f1620e7b5c21e13c046f437b4730d0ca0779288b4d5c3186e55502c23f1ddf6
7
- data.tar.gz: f9ff63e670a1bd2bc334c405b4cb9ad47a944bd23ee7950a2fbfe3925bc637111eeec735400ef091743ab0c8a98d4c730b27f78e44557112f42f2aa4bd71cf31
6
+ metadata.gz: 0d0b8305fd526f1f677d77554b466b6264f95cb6fe1ad2b586a5cc4e82e8963cae7ce45dd2cd10b6d475ef4545175d3e2c5818a4985416a54158c69b0e8d6543
7
+ data.tar.gz: 29b46515c9bfd855198f712468ea687d7441dc90635c004e7d86c9313a51735a296e1cc84b94864f3d043e7e2b328dc7b9a386c352860852b77162e3d825c921
@@ -7,7 +7,7 @@ module Caddie
7
7
 
8
8
  def get_markets( region_id, type_id )
9
9
 
10
- debug = ENV[ 'CADDIE_DEBUG_MODE' ] && ENV[ 'CADDIE_DEBUG_MODE' ].downcase == 'true'
10
+ debug = ENV[ 'EBS_DEBUG_MODE' ] && ENV[ 'EBS_DEBUG_MODE' ].downcase == 'true'
11
11
 
12
12
  type_url = "https://crest-tq.eveonline.com/inventory/types/#{type_id}"
13
13
  items, connections_count = get_multipage_data( "market/#{region_id}/history/?type=#{type_url}", debug )
@@ -8,18 +8,26 @@ module Caddie
8
8
 
9
9
  extend Caddie::CrestDataRetriever
10
10
 
11
+ NB_THREADS=4
12
+
11
13
  def self.update
12
14
  current_path = File.dirname( __FILE__ )
13
15
  request = File.open( "#{current_path}/update_table.sql" ).read
14
16
  ActiveRecord::Base.connection.execute( request )
15
17
  end
16
18
 
17
- def self.feed_price_histories
19
+ def self.feed_price_histories( thread_id = nil )
18
20
  total_connections_counts = 0
19
21
  total_inserts = 0
20
22
  date_deb = Time.now
21
23
 
22
- daily_operations_list.joins( :eve_item, :region ).pluck( :eve_item_id, :region_id, :cpp_eve_item_id, :cpp_region_id ).each do |row|
24
+ dol = daily_operations_list
25
+
26
+ # pp dol.to_a
27
+ dol = dol.where( thread_slice_id: thread_id ) if thread_id
28
+
29
+ # puts dol.reload.count
30
+ dol.joins( :eve_item, :region ).pluck( :eve_item_id, :region_id, :cpp_eve_item_id, :cpp_region_id ).each do |row|
23
31
 
24
32
  # puts "Processing row = #{row}"
25
33
 
@@ -30,6 +38,7 @@ module Caddie
30
38
 
31
39
  ActiveRecord::Base.transaction do
32
40
 
41
+ # TODO : This operation is extremely costly. Keep the last updated timestamp and use it to shorten insert.
33
42
  # puts 'About to reject already used lines'
34
43
  timestamps = CrestPriceHistory.where( region_id: region_id, eve_item_id: eve_item_id ).pluck( :day_timestamp ).to_set
35
44
  items.reject! do |item|
@@ -39,7 +48,6 @@ module Caddie
39
48
  end
40
49
  # puts 'Lines rejected'
41
50
 
42
-
43
51
  items.each do |item_data|
44
52
 
45
53
  date_info = DateTime.parse( item_data['date'] )
@@ -1,6 +1,43 @@
1
- class MThreadedUpdater
1
+ require 'thwait'
2
+ require 'matrix'
3
+
4
+ class Caddie::MThreadedUpdater
2
5
 
3
6
  # TODO : - split the work in database using thread_slice_id (set numbers : 1 .. MAX_THREADS)
4
7
  # TODO : Then run N threads each threads get the records associated to it's number
5
8
 
9
+ def initialize( max_threads, daily_operations_list )
10
+ @max_threads = max_threads
11
+ @daily_operations_list = daily_operations_list
12
+ end
13
+
14
+ def feed_price_histories_threaded
15
+ Thread::abort_on_exception = true
16
+ threads = []
17
+ 0.upto( @max_threads-1 ).each do |thread_id|
18
+ threads << Thread.new {
19
+ puts Thread.inspect
20
+ Thread.current[:timings] = Caddie::CrestPriceHistoryUpdate.feed_price_histories( thread_id )
21
+ }
22
+ end
23
+ result = []
24
+ ThreadsWait.all_waits( *threads ) do |t|
25
+ thread_result = t[:timings]
26
+ result << thread_result
27
+ end
28
+ tmp = result.map { |a| Vector[*a] }.inject(:+)
29
+ tmp.to_a
30
+ end
31
+
32
+ def split_work_for_threads
33
+ ids = @daily_operations_list.pluck( :id )
34
+ ActiveRecord::Base.transaction do
35
+ slice_size = ids.count/@max_threads + 1
36
+ ( 0 ... @max_threads ).each do |thread_id|
37
+ ids_slice = ids.shift( slice_size )
38
+ @daily_operations_list.where( id: ids_slice ).update_all( thread_slice_id: thread_id )
39
+ end
40
+ end
41
+ end
42
+
6
43
  end
@@ -0,0 +1,4 @@
1
+ class CrestPriceHistory < ActiveRecord::Base
2
+ belongs_to :region
3
+ belongs_to :eve_item
4
+ end
@@ -0,0 +1,8 @@
1
+ class AddIndexesToCrestPriceHistoryUpdate < ActiveRecord::Migration
2
+ def change
3
+ add_index :caddie_crest_price_history_updates, :nb_days
4
+ add_index :caddie_crest_price_history_updates, :process_queue
5
+ add_index :caddie_crest_price_history_updates, :next_process_date
6
+ add_index :caddie_crest_price_history_updates, :thread_slice_id
7
+ end
8
+ end
@@ -1,3 +1,3 @@
1
1
  module Caddie
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -6,14 +6,19 @@ namespace :caddie do
6
6
  start_time = Time.now
7
7
  feed_date = start_time.to_date
8
8
 
9
- puts 'About to compute crest_price_history_updates'
10
- Caddie::CrestPriceHistoryUpdate.update
9
+ unless ENV[ 'EBS_NO_HIST_UPDATE' ] && ENV[ 'EBS_NO_HIST_UPDATE' ].downcase == 'true'
10
+ puts 'About to compute crest_price_history_updates'
11
+ Caddie::CrestPriceHistoryUpdate.update
12
+ end
11
13
 
12
14
  end_update_time = Time.now
13
15
  update_planning_time = end_update_time - start_time
14
16
 
15
17
  puts 'About to feed crest_price_histories'
16
- total_inserts, total_connections, total_time = Caddie::CrestPriceHistoryUpdate.feed_price_histories
18
+ total_inserts, total_connections, total_time = Caddie::CrestPriceHistoryUpdate.feed_price_histories
19
+ th = Caddie::MThreadedUpdater.new( Caddie::CrestPriceHistoryUpdate::NB_THREADS, Caddie::CrestPriceHistoryUpdate.daily_operations_list )
20
+ th.split_work_for_threads
21
+ total_inserts, total_connections, total_time = th.feed_price_histories_threaded
17
22
  puts "#{total_inserts} insertions, #{total_connections} connections in #{total_time.round( 2 )} seconds. #{(total_connections/total_time).round( 2 )} co/sec"
18
23
 
19
24
  end_feeding_time = Time.now
@@ -0,0 +1,53 @@
1
+ require 'mocha/api'
2
+ require 'minitest'
3
+
4
+ include Mocha::API
5
+ include FactoryGirl::Syntax::Methods
6
+
7
+ require_relative '../../test/dummy/app/models/eve_item'
8
+ require_relative '../../test/dummy/app/models/region'
9
+ require_relative '../../test/factories/caddie/eve_items'
10
+ require_relative '../../test/factories/caddie/regions'
11
+ require_relative '../../app/models/caddie/crest_data_retriever'
12
+ require_relative '../../app/models/caddie/crest_price_history_update'
13
+ require_relative '../../test/factories/caddie/crest_price_history_updates'
14
+
15
+ # Regular test unit does not commit between insertions, this algo rely on database to split work between threads
16
+ # So we have to fake a test outside the test unit
17
+ namespace :test do
18
+
19
+ desc "M threaded uptader test"
20
+ task :m_threaded_uptader_test=> :environment do
21
+ if (ENV['RAILS_ENV'] == "test") # protect against execution in dev mode
22
+
23
+ Caddie::CrestPriceHistoryUpdate.stubs( :get_multipage_data ).returns( [ [], 5 ] )
24
+
25
+ Region.delete_all
26
+ EveItem.delete_all
27
+ Caddie::CrestPriceHistoryUpdate.delete_all
28
+
29
+ next_process_date = Time.now.to_date
30
+ region = create( :caddie_heimatar )
31
+ 1.upto( 53 ).each do
32
+ item = create( :caddie_eve_item )
33
+ create( :crest_price_history_update, region: region, eve_item: item, next_process_date: next_process_date )
34
+ end
35
+
36
+ th = Caddie::MThreadedUpdater.new( 4, Caddie::CrestPriceHistoryUpdate.daily_operations_list )
37
+ th.split_work_for_threads
38
+ timings = th.feed_price_histories_threaded
39
+ # pp timings
40
+ unless 53 == timings[1]/5
41
+ "Test failed : #{timings[1]/5} != 53"
42
+ else
43
+ puts 'Test passed'
44
+ end
45
+ else
46
+ puts 'Can be only executed in test env'
47
+ end
48
+
49
+ Region.delete_all
50
+ EveItem.delete_all
51
+ Caddie::CrestPriceHistoryUpdate.delete_all
52
+ end
53
+ end
@@ -0,0 +1,53 @@
1
+ # require 'open-uri'
2
+ # # require 'open-uri/cached'
3
+ require 'pp'
4
+
5
+ class EveItem < ActiveRecord::Base
6
+
7
+ # include Assert
8
+ # include ItemsInit::ItemSetupAndComp
9
+ # extend ItemsInit::ItemSetupAndCompSelf
10
+ # extend MultiplePriceRetriever
11
+ # extend Setup::UpdateEveItems
12
+
13
+ has_and_belongs_to_many :users
14
+ has_one :blueprint, dependent: :destroy
15
+ has_many :materials, through: :blueprint
16
+ has_many :components, through: :materials
17
+ belongs_to :market_group
18
+ has_many :crest_price_histories, dependent: :destroy
19
+ has_many :crest_prices_last_month_averages, dependent: :destroy
20
+
21
+ # Itemps containing non ascii characters
22
+ UNPROCESSABLE_ITEMS=[34457,34458,34459,34460,34461,34462,34463,34464,34465,34466,34467,34468,34469,34470,34471,34472,
23
+ 34473,34474,34475,34476,34477,34478,34479,34480,30952,32371,32372]
24
+
25
+ AVG_INDUSTRY_TAX = 0.11 # 10 % base + 1 % system costs (assuming players are smart enough to go in low cost systems)
26
+
27
+ def self.to_eve_item_id(cpp_eve_item_id)
28
+ eve_item=EveItem.where( 'cpp_eve_item_id=?', cpp_eve_item_id).first
29
+ eve_item ? eve_item.id : nil
30
+ end
31
+
32
+ def self.used_items
33
+ used_items, _ = User.get_used_items_and_trade_hubs
34
+ used_items
35
+ end
36
+
37
+ def single_unit_cost
38
+ (cost*(1+AVG_INDUSTRY_TAX))/blueprint.prod_qtt if cost && blueprint
39
+ end
40
+
41
+ def pcent_margin( price )
42
+ (price / single_unit_cost)-1 if price && single_unit_cost
43
+ end
44
+
45
+ def margin( price )
46
+ price - single_unit_cost if price && single_unit_cost
47
+ end
48
+
49
+ def full_batch_size
50
+ blueprint.nb_runs*blueprint.prod_qtt if blueprint
51
+ end
52
+
53
+ end
@@ -0,0 +1,4 @@
1
+ class Region < ActiveRecord::Base
2
+ has_many :trade_hubs
3
+ has_many :crest_prices_last_month_averages
4
+ end
@@ -9,11 +9,11 @@ default: &default
9
9
  timeout: 5000
10
10
  adapter: postgresql
11
11
  encoding: unicode
12
- username: eve_business_server
12
+ username: caddie
13
13
 
14
14
  development:
15
15
  <<: *default
16
- database: eve_business_server_dev
16
+ database: caddie_dev
17
17
 
18
18
 
19
19
  # Warning: The database defined as "test" will be erased and
@@ -21,4 +21,4 @@ development:
21
21
  # Do not set this db to the same as development or production.
22
22
  test:
23
23
  <<: *default
24
- database: eve_business_server_test
24
+ database: caddie_test
@@ -0,0 +1,11 @@
1
+ class CreateEveItems < ActiveRecord::Migration
2
+ def change
3
+ create_table :eve_items do |t|
4
+ t.integer :eve_item_id
5
+ t.string :name
6
+
7
+ t.timestamps
8
+ end
9
+ add_index :eve_items, :eve_item_id
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class AddNameLowcaseToEveItem < ActiveRecord::Migration
2
+ def change
3
+ add_column :eve_items, :name_lowcase, :string
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class RenameEveItemId < ActiveRecord::Migration
2
+ def change
3
+ rename_column :eve_items, :eve_item_id, :cpp_eve_item_id
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddCostToEveItem < ActiveRecord::Migration
2
+ def change
3
+ add_column :eve_items, :cost, :float
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class AddCppMarketGroupIdToEveItem < ActiveRecord::Migration
2
+ def change
3
+ add_column :eve_items, :cpp_market_group_id, :integer
4
+ add_index :eve_items, :cpp_market_group_id
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddInvolvedInBlueprintToEveItem < ActiveRecord::Migration
2
+ def change
3
+ add_column :eve_items, :involved_in_blueprint, :bool, default: false, index: true
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class CreateRegions < ActiveRecord::Migration
2
+ def change
3
+ create_table :regions do |t|
4
+ t.string :cpp_region_id, null: false
5
+ t.string :name, null: false
6
+
7
+ t.timestamps null: false
8
+ end
9
+ add_index :regions, :cpp_region_id, unique: true
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ class CreateCrestPriceHistories < ActiveRecord::Migration
2
+ def change
3
+ create_table :crest_price_histories do |t|
4
+ t.references :region, index: true, foreign_key: true, null: false
5
+ t.references :eve_item, index: true, foreign_key: true, null: false
6
+ t.string :day_timestamp, index: true, null: false
7
+ t.timestamp :history_date, null: false
8
+ t.column :order_count, :bigint
9
+ t.column :volume, :bigint
10
+ t.float :low_price
11
+ t.float :avg_price
12
+ t.float :high_price
13
+
14
+ t.timestamps null: false
15
+ end
16
+ add_index :crest_price_histories, [:region_id, :eve_item_id, :day_timestamp], unique: true, name: 'price_histories_all_keys_index'
17
+ end
18
+ end