Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-03 03:08:11 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-03 03:08:11 +0300
commitbd8fb5668ae739a83d55ec5ca4a04344eef2167e (patch)
treebaf085c6cd58b3b5e5a192d4d3db360d623bb056 /lib/grafana
parent561e1b470f0a99fe6304c8f197348c47a637d594 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/grafana')
-rw-r--r--lib/grafana/time_window.rb130
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/grafana/time_window.rb b/lib/grafana/time_window.rb
new file mode 100644
index 00000000000..111e3ab7de2
--- /dev/null
+++ b/lib/grafana/time_window.rb
@@ -0,0 +1,130 @@
+# frozen_string_literal: true
+
+module Grafana
+ # Allows for easy formatting and manipulations of timestamps
+ # coming from a Grafana url
+ class TimeWindow
+ include ::Gitlab::Utils::StrongMemoize
+
+ def initialize(from, to)
+ @from = from
+ @to = to
+ end
+
+ def formatted
+ {
+ start: window[:from].formatted,
+ end: window[:to].formatted
+ }
+ end
+
+ def in_milliseconds
+ window.transform_values(&:to_ms)
+ end
+
+ private
+
+ def window
+ strong_memoize(:window) do
+ specified_window
+ rescue Timestamp::Error
+ default_window
+ end
+ end
+
+ def specified_window
+ RangeWithDefaults.new(
+ from: Timestamp.from_ms_since_epoch(@from),
+ to: Timestamp.from_ms_since_epoch(@to)
+ ).to_hash
+ end
+
+ def default_window
+ RangeWithDefaults.new.to_hash
+ end
+ end
+
+ # For incomplete time ranges, adds default parameters to
+ # achieve a complete range. If both full range is provided,
+ # range will be returned.
+ class RangeWithDefaults
+ DEFAULT_RANGE = 8.hours
+
+ # @param from [Grafana::Timestamp, nil] Start of the expected range
+ # @param to [Grafana::Timestamp, nil] End of the expected range
+ def initialize(from: nil, to: nil)
+ @from = from
+ @to = to
+
+ apply_defaults!
+ end
+
+ def to_hash
+ { from: @from, to: @to }.compact
+ end
+
+ private
+
+ def apply_defaults!
+ @to ||= @from ? relative_end : Timestamp.new(Time.now)
+ @from ||= relative_start
+ end
+
+ def relative_start
+ Timestamp.new(DEFAULT_RANGE.before(@to.time))
+ end
+
+ def relative_end
+ Timestamp.new(DEFAULT_RANGE.since(@from.time))
+ end
+ end
+
+ # Offers a consistent API for timestamps originating from
+ # Grafana or other sources, allowing for formatting of timestamps
+ # as consumed by Grafana-related utilities
+ class Timestamp
+ Error = Class.new(StandardError)
+
+ attr_accessor :time
+
+ # @param timestamp [Time]
+ def initialize(time)
+ @time = time
+ end
+
+ # Formats a timestamp from Grafana for compatibility with
+ # parsing in JS via `new Date(timestamp)`
+ def formatted
+ time.utc.strftime('%FT%TZ')
+ end
+
+ # Converts to milliseconds since epoch
+ def to_ms
+ time.to_i * 1000
+ end
+
+ class << self
+ # @param time [String] Representing milliseconds since epoch.
+ # This is what JS "decided" unix is.
+ def from_ms_since_epoch(time)
+ return if time.nil?
+
+ raise Error.new('Expected milliseconds since epoch') unless ms_since_epoch?(time)
+
+ new(cast_ms_to_time(time))
+ end
+
+ private
+
+ def cast_ms_to_time(time)
+ Time.at(time.to_i / 1000.0)
+ end
+
+ def ms_since_epoch?(time)
+ ms = time.to_i
+
+ ms.to_s == time && ms.bit_length < 64
+ end
+ end
+ end
+end