Class: Stockboy::Job

Inherits:
Object
  • Object
show all
Defined in:
lib/stockboy/job.rb

Overview

This class wraps up the main interface for the process of fetching, parsing and sorting data. When used with a predefined template file, you can pass the name of the template to define it. This is the common way to use Stockboy:

job = Stockboy::Job.define('my_template')
if job.process
  job.records[:update].each do |r|
    # ...
  end
  job.records[:cancel].each do |r|
    # ...
  end
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) { ... } ⇒ Job

Initialize a new job

Parameters:

  • params (Hash) (defaults to: {})

Options Hash (params):

Yields:

  • instance for further configuration or processing



83
84
85
86
87
88
89
90
91
92
# File 'lib/stockboy/job.rb', line 83

def initialize(params={}, &block)
  @provider   = params[:provider]
  @reader     = params[:reader]
  @attributes = params[:attributes] || AttributeMap.new
  @filters    = FilterChain.new params[:filters]
  @triggers   = Hash.new { |h,k| h[k] = [] }
  @triggers.replace params[:triggers] if params[:triggers]
  yield self if block_given?
  reset
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



155
156
157
158
159
160
161
# File 'lib/stockboy/job.rb', line 155

def method_missing(name, *args)
  if triggers.key?(name)
    trigger(name, *args)
  else
    super
  end
end

Instance Attribute Details

#all_recordsArray<CandidateRecord> (readonly)

List of all records, filtered or not

Returns:



72
73
74
# File 'lib/stockboy/job.rb', line 72

def all_records
  @all_records
end

#attributesAttributeMap

Configures the mapping & translation of raw data fields

Returns:



43
44
45
# File 'lib/stockboy/job.rb', line 43

def attributes
  @attributes
end

#filtersFilterChain

List of filters for sorting processed records

Filters are applied in order, first match will capture the record. Records that don’t match any

Returns:



52
53
54
# File 'lib/stockboy/job.rb', line 52

def filters
  @filters
end

#providerProvider

Defines the data source for receiving data

Returns:



31
32
33
# File 'lib/stockboy/job.rb', line 31

def provider
  @provider
end

#readerReader

Defines the format for parsing received data

Returns:



37
38
39
# File 'lib/stockboy/job.rb', line 37

def reader
  @reader
end

#recordsHash{Symbol=>Array} (readonly)

Lists of records grouped by filter key

Returns:

  • (Hash{Symbol=>Array})


60
61
62
# File 'lib/stockboy/job.rb', line 60

def records
  @records
end

#total_recordsInteger (readonly)

Count of all processed records

Returns:

  • (Integer)


132
133
134
# File 'lib/stockboy/job.rb', line 132

def total_records
  @all_records.size
end

#triggersObject

Returns the value of attribute triggers.



54
55
56
# File 'lib/stockboy/job.rb', line 54

def triggers
  @triggers
end

#unfiltered_recordsArray<CandidateRecord> (readonly)

List of records not matched by any filter

Returns:



66
67
68
# File 'lib/stockboy/job.rb', line 66

def unfiltered_records
  @unfiltered_records
end

Class Method Details

.define(template_name) { ... } ⇒ Object

Instantiate a job configured by DSL template file

Parameters:

  • template_name (String)

    File basename from template load path

Yields:

  • instance for further configuration or processing

See Also:



100
101
102
103
104
105
# File 'lib/stockboy/job.rb', line 100

def self.define(template_name)
  return nil unless template = TemplateFile.read(template_name)
  job = Configurator.new(template, TemplateFile.find(template_name)).to_job
  yield job if block_given?
  job
end

Instance Method Details

#data(&block) ⇒ Object



119
120
121
# File 'lib/stockboy/job.rb', line 119

def data(&block)
  provider.data(&block)
end

#data?(reduction = :all?) ⇒ Boolean

Returns:

  • (Boolean)


123
124
125
# File 'lib/stockboy/job.rb', line 123

def data?(reduction=:all?)
  provider.data?(reduction)
end

#inspectString

Overview of the job configuration; tries to be less noisy by hiding sub-element details.

Returns:

  • (String)


198
199
200
201
202
203
204
205
# File 'lib/stockboy/job.rb', line 198

def inspect
  prov = "provider=#{Providers.all.key(provider.class) || provider.class}"
  read = "reader=#{Readers.all.key(reader.class) || reader.class}"
  attr = "attributes=#{attributes.map(&:to)}"
  filt = "filters=#{filters.keys}"
  cnts = "record_counts=#{record_counts}"
  "#<#{self.class}:#{self.object_id} #{prov}, #{read}, #{attr}, #{filt}, #{cnts}>"
end

#processBoolean

Fetch data and process it into groups of filtered records

Returns:

  • (Boolean)

    Success or failure



111
112
113
114
115
116
117
# File 'lib/stockboy/job.rb', line 111

def process
  with_query_caching do
    load_records
    yield @records if block_given?
  end
  provider.errors.empty?
end

#processed?Boolean

Has the job been processed successfully?

Returns:

  • (Boolean)


189
190
191
# File 'lib/stockboy/job.rb', line 189

def processed?
  !!@processed
end

#record_countsHash{Symbol=>Integer}

Counts of processed records grouped by filter key

Returns:

  • (Hash{Symbol=>Integer})


140
141
142
# File 'lib/stockboy/job.rb', line 140

def record_counts
  @records.reduce(Hash.new) { |a, (k,v)| a[k] = v.size; a }
end

#trigger(key, *args) ⇒ Object



148
149
150
151
152
153
# File 'lib/stockboy/job.rb', line 148

def trigger(key, *args)
  return nil unless triggers.key?(key)
  triggers[key].each do |c|
    c.call(self, *args)
  end
end