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.
- checksums.yaml +4 -4
- data/app/models/caddie/crest_data_retriever.rb +1 -1
- data/app/models/caddie/crest_price_history_update.rb +11 -3
- data/app/models/caddie/m_threaded_updater.rb +38 -1
- data/app/models/crest_price_history.rb +4 -0
- data/db/migrate/20160725091214_add_indexes_to_crest_price_history_update.rb +8 -0
- data/lib/caddie/version.rb +1 -1
- data/lib/tasks/caddie_tasks.rake +8 -3
- data/lib/tasks/m_threaded_updater_test.rake +53 -0
- data/test/dummy/app/models/eve_item.rb +53 -0
- data/test/dummy/app/models/region.rb +4 -0
- data/test/dummy/config/database.yml +3 -3
- data/test/dummy/db/migrate/20150410082132_create_eve_items.rb +11 -0
- data/test/dummy/db/migrate/20150414095303_add_name_lowcase_to_eve_item.rb +5 -0
- data/test/dummy/db/migrate/20150416154256_rename_eve_item_id.rb +5 -0
- data/test/dummy/db/migrate/20150417135716_add_cost_to_eve_item.rb +5 -0
- data/test/dummy/db/migrate/20150906171550_add_cpp_market_group_id_to_eve_item.rb +6 -0
- data/test/dummy/db/migrate/20150909162142_add_involved_in_blueprint_to_eve_item.rb +5 -0
- data/test/dummy/db/migrate/20150910074544_create_regions.rb +11 -0
- data/test/dummy/db/migrate/20150910080646_create_crest_price_histories.rb +18 -0
- data/test/dummy/db/schema.rb +19 -299
- data/test/dummy/log/development.log +446 -54107
- data/test/dummy/log/test.log +46048 -0
- data/test/factories/caddie/crest_price_history_updates.rb +4 -0
- data/test/factories/caddie/eve_items.rb +54 -0
- data/test/factories/caddie/regions.rb +33 -0
- data/test/models/caddie/crest_price_history_update_test.rb +19 -4
- data/test/models/caddie/m_threaded_updater_test.rb +26 -0
- data/test/test_helper.rb +10 -0
- metadata +72 -30
- data/app/models/crest_price_history.rb +0 -1
- data/app/models/eve_item.rb +0 -1
- data/app/models/region.rb +0 -1
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dec5dc1e0bf8562abd8ce5afcbefcb44ef4d0f4c
|
4
|
+
data.tar.gz: b27051154d8eb7d652ad9dc79b0f91397ca6fc75
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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[ '
|
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
|
-
|
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
|
-
|
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,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
|
data/lib/caddie/version.rb
CHANGED
data/lib/tasks/caddie_tasks.rake
CHANGED
@@ -6,14 +6,19 @@ namespace :caddie do
|
|
6
6
|
start_time = Time.now
|
7
7
|
feed_date = start_time.to_date
|
8
8
|
|
9
|
-
|
10
|
-
|
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
|
@@ -9,11 +9,11 @@ default: &default
|
|
9
9
|
timeout: 5000
|
10
10
|
adapter: postgresql
|
11
11
|
encoding: unicode
|
12
|
-
username:
|
12
|
+
username: caddie
|
13
13
|
|
14
14
|
development:
|
15
15
|
<<: *default
|
16
|
-
database:
|
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:
|
24
|
+
database: caddie_test
|
@@ -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
|