Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PLAT-11363] Use new idempotent API for mazerunner command fetch #231

Merged
merged 5 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
source 'https://rubygems.org'

gem 'bugsnag-maze-runner', '~>8.4.0'
gem 'bugsnag-maze-runner', '~>8.14.0'

#gem 'bugsnag-maze-runner', git: 'https://github.com/bugsnag/maze-runner', branch: 'integration/v8'

Expand Down
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ GEM
selenium-webdriver (~> 4.2, < 4.6)
bugsnag (6.26.0)
concurrent-ruby (~> 1.0)
bugsnag-maze-runner (8.4.1)
bugsnag-maze-runner (8.14.1)
appium_lib (~> 12.0.0)
appium_lib_core (~> 5.4.0)
bugsnag (~> 6.24)
Expand Down Expand Up @@ -82,9 +82,9 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2023.1205)
multi_test (0.1.2)
nokogiri (1.15.5-arm64-darwin)
nokogiri (1.16.0-arm64-darwin)
racc (~> 1.4)
nokogiri (1.15.5-x86_64-darwin)
nokogiri (1.16.0-x86_64-darwin)
racc (~> 1.4)
optimist (3.0.1)
os (1.0.1)
Expand Down Expand Up @@ -123,7 +123,7 @@ PLATFORMS
x86_64-darwin-20

DEPENDENCIES
bugsnag-maze-runner (~> 8.4.0)
bugsnag-maze-runner (~> 8.14.0)

BUNDLED WITH
2.3.18
54 changes: 42 additions & 12 deletions features/fixtures/ios/Fixture/CommandReaderThread.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import os
class CommandReaderThread: Thread {
var fixtureConfig: FixtureConfig
var commandReceiver: CommandReceiver
var lastCommandID: String = ""

init(fixtureConfig: FixtureConfig, commandReceiver: CommandReceiver) {
self.fixtureConfig = fixtureConfig
Expand All @@ -29,29 +30,53 @@ class CommandReaderThread: Thread {
}
}

func receiveNextCommand() {
let fetchTask = CommandFetchTask(url: fixtureConfig.commandURL)
func newStartedFetchTask() -> CommandFetchTask {
let fetchTask = CommandFetchTask(url: fixtureConfig.commandURL, afterCommandID: lastCommandID)
fetchTask.start()
return fetchTask
}

func receiveNextCommand() {
let maxWaitTime = 5.0
let pollingInterval = 1.0

var fetchTask = newStartedFetchTask()
let startTime = Date()

while true {
Thread.sleep(forTimeInterval: pollingInterval)
switch fetchTask.state {
case CommandFetchState.success:
commandReceiver.receiveCommand(command: fetchTask.command!)
logDebug("Command fetch: Request succeeded")
let command = fetchTask.command!
lastCommandID = command.uuid
commandReceiver.receiveCommand(command: command)
return
case CommandFetchState.fetching:
logDebug("Command fetch server hasn't responded yet, waiting 1 second more...")
Thread.sleep(forTimeInterval: 1)
let duration = Date() - startTime
if duration < maxWaitTime {
logDebug("Command fetch: Server hasn't responded in \(duration)s (max \(maxWaitTime)). Waiting \(pollingInterval)s more...")
} else {
fetchTask.cancel()
logInfo("Command fetch: Server hasn't responded in \(duration)s (max \(maxWaitTime)). Trying again...")
fetchTask = newStartedFetchTask()
}
break
case CommandFetchState.failed:
logInfo("Command fetch request failed. Trying again...")
Thread.sleep(forTimeInterval: 1)
fetchTask.start()
logInfo("Command fetch: Request failed. Trying again...")
fetchTask = newStartedFetchTask()
break
}
}
}
}

extension Date {
static func - (lhs: Date, rhs: Date) -> TimeInterval {
return lhs.timeIntervalSinceReferenceDate - rhs.timeIntervalSinceReferenceDate
}
}

enum CommandFetchState {
case failed, fetching, success
}
Expand All @@ -60,16 +85,21 @@ class CommandFetchTask {
var url: URL
var state = CommandFetchState.failed
var command: MazeRunnerCommand?
var task: URLSessionTask?

init(url: URL, afterCommandID: String) {
self.url = URL(string: "\(url.absoluteString)?after=\(afterCommandID)")!
}

init(url: URL) {
self.url = url
func cancel() {
task?.cancel()
}

func start() {
logInfo("Fetching next command from \(url)")
state = CommandFetchState.fetching
let request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
Expand All @@ -88,6 +118,6 @@ class CommandFetchTask {
logError("Failed to fetch command: HTTP Request to \(String(describing: self.url)) failed: \(error)")
}
}
task.resume()
task?.resume()
}
}
5 changes: 4 additions & 1 deletion features/fixtures/ios/Fixture/MazeRunnerCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ import Foundation
class MazeRunnerCommand: Codable {
let message: String
let action: String
let uuid: String
let args: Array<String>

init(action: String, args: Array<String>, message: String) {
init(uuid: String, action: String, args: Array<String>, message: String) {
self.uuid = uuid
self.message = message
self.action = action
self.args = args
}

required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.uuid = try container.decodeIfPresent(String.self, forKey: .uuid) ?? ""
self.message = try container.decodeIfPresent(String.self, forKey: .message) ?? ""
self.action = try container.decodeIfPresent(String.self, forKey: .action) ?? ""
self.args = try container.decodeIfPresent(Array<String>.self, forKey: .args) ?? []
Expand Down
13 changes: 8 additions & 5 deletions features/fixtures/ios/Scenarios/Scenario.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,17 @@ class Scenario: NSObject {
}

func isMazeRunnerAdministrationURL(url: URL) -> Bool {
switch url {
case fixtureConfig.tracesURL, fixtureConfig.commandURL, fixtureConfig.metricsURL:
if url.absoluteString.hasPrefix(fixtureConfig.tracesURL.absoluteString) ||
url.absoluteString.hasPrefix(fixtureConfig.commandURL.absoluteString) ||
url.absoluteString.hasPrefix(fixtureConfig.metricsURL.absoluteString) {
return true
case fixtureConfig.reflectURL:
}

if url.absoluteString.hasPrefix(fixtureConfig.reflectURL.absoluteString) {
return false // reflectURL is fair game!
default:
return false
}

return false
}

func reportMeasurements() {
Expand Down
Loading