Class: Lavin::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/lavin/runner.rb

Defined Under Namespace

Classes: Entry

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(personas: nil) ⇒ Runner

Returns a new instance of Runner.



79
80
81
82
83
84
85
# File 'lib/lavin/runner.rb', line 79

def initialize(personas: nil)
  @personas = personas || User.personas
  @remaining = @personas.map { |persona| Entry.new(persona) }
  @total_users = @remaining.sum(&:count)
  @spawned_users = 0
  @index = -1
end

Class Attribute Details

.threadObject

Returns the value of attribute thread.



41
42
43
# File 'lib/lavin/runner.rb', line 41

def thread
  @thread
end

Instance Attribute Details

#indexObject

Returns the value of attribute index.



38
39
40
# File 'lib/lavin/runner.rb', line 38

def index
  @index
end

#personasObject (readonly)

Returns the value of attribute personas.



37
38
39
# File 'lib/lavin/runner.rb', line 37

def personas
  @personas
end

#remainingObject (readonly)

Returns the value of attribute remaining.



37
38
39
# File 'lib/lavin/runner.rb', line 37

def remaining
  @remaining
end

#spawned_usersObject

Returns the value of attribute spawned_users.



38
39
40
# File 'lib/lavin/runner.rb', line 38

def spawned_users
  @spawned_users
end

#total_usersObject (readonly)

Returns the value of attribute total_users.



37
38
39
# File 'lib/lavin/runner.rb', line 37

def total_users
  @total_users
end

Class Method Details

.running?Boolean

Returns:

  • (Boolean)


70
71
72
73
74
75
76
# File 'lib/lavin/runner.rb', line 70

def running?
  return false unless thread
  return true if %w[run sleep].include? thread.status

  stop
  false
end

.startObject



47
48
49
# File 'lib/lavin/runner.rb', line 47

def start
  new.start
end

.start_asyncObject



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/lavin/runner.rb', line 51

def start_async
  self.thread = Thread.new do
    new.start
    stop
    exit
  end
rescue StandardError => error
  puts "Failed to run in thread: #{error.message}"
  thread.join
  self.thread = nil
  raise
end

.stopObject



64
65
66
67
68
# File 'lib/lavin/runner.rb', line 64

def stop
  thread&.kill
  self.thread = nil
  Statistics.stop
end

.yieldObject



43
44
45
# File 'lib/lavin/runner.rb', line 43

def yield
  Async::Task.current.yield if Async::Task.current?
end

Instance Method Details

#create_async_taskObject



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/lavin/runner.rb', line 96

def create_async_task
  @task = Async(annotation: "Main") do |task|
    spawn(count: total_users) do |persona|
      next unless persona

      user_index = spawned_users
      annotation = "User: #{persona.name} ##{user_index}"
      task.async(annotation:) do |user_task|
        user = persona.new(user_index:, task: user_task)
        user.run
      ensure
        user.cleanup
      end
    end
  end
end

#next_personaObject



132
133
134
135
136
137
138
139
140
141
# File 'lib/lavin/runner.rb', line 132

def next_persona
  self.index += 1

  entry = remaining[index % remaining.size]
  if entry.present?
    entry.get
  elsif remaining.any?(&:present?)
    next_persona
  end
end

#spawn(count: 1) ⇒ Object



122
123
124
125
126
127
128
129
130
# File 'lib/lavin/runner.rb', line 122

def spawn(count: 1)
  count.times do
    persona = next_persona
    break unless persona

    self.spawned_users += 1
    yield persona
  end
end

#startObject



87
88
89
90
91
92
93
94
# File 'lib/lavin/runner.rb', line 87

def start
  Statistics.meassure { create_async_task }
rescue StandardError => error
  puts "Failed to run tasks: #{error.message}"
  raise
ensure
  stop
end

#stopObject



117
118
119
120
# File 'lib/lavin/runner.rb', line 117

def stop
  @task&.stop
  @task&.wait
end

#waitObject



113
114
115
# File 'lib/lavin/runner.rb', line 113

def wait
  @task&.wait
end