Skip to content

Commit

Permalink
Allow float times
Browse files Browse the repository at this point in the history
  • Loading branch information
jmthomas committed Jul 8, 2024
1 parent 98629f2 commit fe1f527
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 12 deletions.
13 changes: 7 additions & 6 deletions openc3/lib/openc3/models/activity_model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ActivityModel < Model
# with 15 slots to make sure we don't miss a planned task.
# @return [Array|nil] Array of the next hour in the sorted set
def self.activities(name:, scope:)
now = Time.now.to_i
now = Time.now.to_f
start_score = now - 15
stop_score = (now + 3660)
array = Store.zrangebyscore("#{scope}#{PRIMARY_KEY}__#{name}", start_score, stop_score)
Expand Down Expand Up @@ -156,7 +156,7 @@ def initialize(
@updated_at = updated_at
end

# validate_time searches from the current activity @stop - 1 (because we allow overlap of stop with start)
# validate_time searches from the current activity @stop (exclusive because we allow overlap of stop with start)
# back through @start - MAX_DURATION. The method is trying to validate that this new activity does not
# overlap with anything else. The reason we search back past @start through MAX_DURATION is because we
# need to return all the activities that may start before us and verify that we don't overlap them.
Expand All @@ -168,7 +168,8 @@ def initialize(
#
# @param [Integer] ignore_score - should be nil unless you want to ignore a time when doing an update
def validate_time(ignore_score = nil)
array = Store.zrevrangebyscore(@primary_key, @stop - 1, @start - MAX_DURATION)
# Adding a '(' makes the max value exclusive
array = Store.zrevrangebyscore(@primary_key, "(#{@stop}", @start - MAX_DURATION)
array.each do |value|
activity = JSON.parse(value, :allow_nan => true, :create_additions => true)
if ignore_score == activity['start']
Expand All @@ -195,14 +196,14 @@ def validate_input(start:, stop:, kind:, data:)
rescue Date::Error
raise ActivityInputError.new "start and stop must be seconds: #{start}, #{stop}"
end
now_i = Time.now.to_i
now_f = Time.now.to_f
begin
duration = stop - start
rescue NoMethodError
raise ActivityInputError.new "start and stop must be seconds: #{start}, #{stop}"
end
if now_i >= start and kind != 'expire'
raise ActivityInputError.new "activity must be in the future, current_time: #{now_i} vs #{start}"
if now_f >= start and kind != 'expire'
raise ActivityInputError.new "activity must be in the future, current_time: #{now_f} vs #{start}"
elsif duration >= MAX_DURATION and kind != 'expire'
raise ActivityInputError.new "activity can not be longer than #{MAX_DURATION} seconds"
elsif duration <= 0
Expand Down
32 changes: 26 additions & 6 deletions openc3/spec/models/activity_model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -238,19 +238,19 @@ def generate_activity(name:, scope:, start:, kind: "COMMAND", stop: 1.0)
it "returns all metrics between X and Y" do
name = "foobar"
scope = "scope"
activity = generate_activity(name: name, scope: scope, start: 1.5, kind: 'SCRIPT')
activity.create()
activity = generate_activity(name: name, scope: scope, start: 5.0, kind: 'SCRIPT')
activity.create()
activity1 = generate_activity(name: name, scope: scope, start: 1.5, kind: 'SCRIPT')
activity1.create()
activity2 = generate_activity(name: name, scope: scope, start: 5.0, kind: 'SCRIPT')
activity2.create()
dt = DateTime.now.new_offset(0)
start = (dt + (1 / 24.0)).strftime("%s").to_i
stop = (dt + (3 / 24.0)).strftime("%s").to_i
array = ActivityModel.get(name: name, scope: scope, start: start, stop: stop)
expect(array.empty?).to eql(false)
expect(array.length).to eql(1)
expect(array[0]["kind"]).to eql("script")
expect(array[0]["start"]).not_to be_nil
expect(array[0]["stop"]).not_to be_nil
expect(array[0]["start"]).to eql(activity1.start)
expect(array[0]["stop"]).to eql(activity1.stop)
end
end

Expand Down Expand Up @@ -288,6 +288,26 @@ def generate_activity(name:, scope:, start:, kind: "COMMAND", stop: 1.0)
expect(model.events.empty?).to eql(false)
expect(model.events.length).to eql(1)
end

it "supports floating point start and stop" do
name = "foobar"
scope = "scope"
activity = ActivityModel.new(
name: name,
scope: scope,
start: (Time.now + 1).to_f,
stop: (Time.now + 1.5).to_f,
kind: "COMMAND",
data: {}
)
activity.create()
model = ActivityModel.score(name: name, scope: scope, score: activity.start)
expect(model.fulfillment).to eql(false)
expect(model.start).to eql(activity.start)
expect(model.stop).to eql(activity.stop)
expect(model.events.empty?).to eql(false)
expect(model.events.length).to eql(1)
end
end

describe "self.count" do
Expand Down

0 comments on commit fe1f527

Please sign in to comment.