Last active
April 27, 2016 18:10
-
-
Save mzaks/addb8ae4e7ae01316dce359969a6d95f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| var machines : [NSURL] = [] | |
| var numberOfTicks = 0 | |
| let loadingQueues = [ // 4 cores -> 4 queues, more cores -> add more queues | |
| dispatch_queue_create("loadingQueue1", nil), | |
| dispatch_queue_create("loadingQueue2", nil), | |
| dispatch_queue_create("loadingQueue3", nil), | |
| dispatch_queue_create("loadingQueue4", nil), | |
| ] | |
| struct CircularBuffer<T> { | |
| private var cursor = 0 | |
| private var firstRound = true | |
| private var buffer : [T] | |
| init(capacity : Int, defaultValue : T){ | |
| buffer = Array.init(count: capacity, repeatedValue: defaultValue) | |
| } | |
| mutating func push(value: T){ | |
| buffer[cursor] = value | |
| cursor += 1 | |
| if cursor == buffer.count { | |
| cursor = 0 | |
| firstRound = false | |
| } | |
| } | |
| var values : ArraySlice<T> { | |
| return firstRound ? buffer[0..<cursor] : buffer[0..<buffer.count] | |
| } | |
| } | |
| var fiveMinutesData : [CircularBuffer<Double>]! | |
| func initFiveMinutesData(){ | |
| fiveMinutesData = Array.init(count: machines.count, repeatedValue: CircularBuffer(capacity:60, defaultValue:0.0)) | |
| } | |
| func loadMachineURLs() { | |
| let url = NSURL(string: "http://machinepark.actyx.io/api/v1/machines") | |
| let array = try! NSJSONSerialization.JSONObjectWithData(NSData(contentsOfURL: url!)!, options: []) as! NSArray | |
| machines = array.map { (urlPart) -> NSURL in | |
| let fullUrlSting = (urlPart as! String).stringByReplacingOccurrencesOfString("$API_ROOT", withString:"http://machinepark.actyx.io/api/v1") | |
| return NSURL(string:fullUrlSting)! | |
| } | |
| } | |
| func tick(){ | |
| while fiveMinutesData.last?.cursor != numberOfTicks % 60 { // waiting for queues to finish | |
| sleep(1) | |
| } | |
| var queueCursor = 0 | |
| for (index, url) in machines.enumerate() { | |
| queueCursor = (queueCursor + 1) % loadingQueues.count | |
| dispatch_async(loadingQueues[queueCursor]) { | |
| let d = NSData(contentsOfURL: url) | |
| if d == nil { | |
| print("Error: \(url)") | |
| fiveMinutesData[index].push(0) // 0 values will be ignored when calculating average | |
| return | |
| } | |
| let data = try! NSJSONSerialization.JSONObjectWithData(d!, options: []) as! NSDictionary | |
| let name = data["name"] as! String | |
| let current = data["current"] as! NSNumber | |
| let alert = data["current_alert"] as! NSNumber | |
| fiveMinutesData[index].push(current.doubleValue) | |
| if current.doubleValue >= alert.doubleValue { | |
| let measurements = fiveMinutesData[index].values | |
| let sum = measurements.reduce((value:0.0, elementsToIgnore:0)){sum,value in | |
| return value == 0 ? (sum.value, sum.elementsToIgnore + 1) : (sum.value + value, sum.elementsToIgnore) | |
| } | |
| let mid = sum.value / Double(measurements.count - sum.elementsToIgnore) | |
| print("Allert! \(name) is at \(current) which is above \(alert), average of last \(measurements.count - sum.elementsToIgnore) measurements is \(mid)") | |
| } | |
| } | |
| } | |
| numberOfTicks += 1 | |
| sleep(5) // collecting data at 0.2Hz best case | |
| } | |
| loadMachineURLs() | |
| initFiveMinutesData() | |
| while true { | |
| tick() | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // main.swift | |
| // ActyxChalangeConsole | |
| // | |
| // Created by Maxim Zaks on 20.04.16. | |
| // Copyright © 2016 maxim.zaks. All rights reserved. | |
| // | |
| import Foundation | |
| var machines : [NSURL] = [] | |
| var numberOfTicks = 0 | |
| let loadingQueues = [ | |
| dispatch_queue_create("loadingQueue1", nil), | |
| dispatch_queue_create("loadingQueue2", nil), | |
| dispatch_queue_create("loadingQueue3", nil), | |
| dispatch_queue_create("loadingQueue4", nil), | |
| ] | |
| class CircularBuffer<T> { | |
| private var cursor = 0 | |
| private var firstRound = true | |
| private var buffer : [T] | |
| init(capacity : Int, defaultValue : T){ | |
| buffer = Array.init(count: capacity, repeatedValue: defaultValue) | |
| } | |
| func push(value: T){ | |
| buffer[cursor] = value | |
| cursor += 1 | |
| if cursor == buffer.count { | |
| cursor = 0 | |
| firstRound = false | |
| } | |
| } | |
| var values : ArraySlice<T> { | |
| return firstRound ? buffer[0..<cursor] : buffer[0..<buffer.count] | |
| } | |
| } | |
| var fiveMinutesData : [CircularBuffer<Double>]! | |
| func initFiveMinutesData(){ | |
| fiveMinutesData = [] | |
| for _ in 0 ..< machines.count { | |
| fiveMinutesData.append(CircularBuffer(capacity: 60, defaultValue: 0.0)) | |
| } | |
| } | |
| func loadMachineURLs() { | |
| let url = NSURL(string: "http://machinepark.actyx.io/api/v1/machines") | |
| let array = try! NSJSONSerialization.JSONObjectWithData(NSData(contentsOfURL: url!)!, options: []) as! NSArray | |
| machines = array.map { (urlPart) -> NSURL in | |
| let fullUrlSting = (urlPart as! String).stringByReplacingOccurrencesOfString("$API_ROOT", withString:"http://machinepark.actyx.io/api/v1") | |
| return NSURL(string:fullUrlSting)! | |
| } | |
| } | |
| func tick(){ | |
| while true { // waiting for queus to finish | |
| if fiveMinutesData[fiveMinutesData.count-1].cursor == numberOfTicks % 60 && | |
| fiveMinutesData[fiveMinutesData.count-2].cursor == numberOfTicks % 60 && | |
| fiveMinutesData[fiveMinutesData.count-3].cursor == numberOfTicks % 60 && | |
| fiveMinutesData[fiveMinutesData.count-4].cursor == numberOfTicks % 60 | |
| { | |
| break | |
| } | |
| print("!!!!!!!!!!") | |
| sleep(1) | |
| } | |
| print("--------") | |
| var queueCursor = 0 | |
| for (index, url) in machines.enumerate() { | |
| queueCursor = (queueCursor + 1) % loadingQueues.count | |
| let queue = loadingQueues[queueCursor] | |
| let buffer = fiveMinutesData[index] | |
| dispatch_async(queue) { | |
| let t = CFAbsoluteTimeGetCurrent() | |
| let d = NSData(contentsOfURL: url) | |
| if d == nil { | |
| print("Error: \(url)") | |
| buffer.push(0) // 0 values will be ignored when calculating average | |
| return | |
| } | |
| let data = try! NSJSONSerialization.JSONObjectWithData(d!, options: []) as! NSDictionary | |
| let name = data["name"] as! String | |
| let current = data["current"] as! NSNumber | |
| let alert = data["current_alert"] as! NSNumber | |
| print(index) | |
| buffer.push(current.doubleValue) | |
| print("\(CFAbsoluteTimeGetCurrent() - t) queue:\(queue) index: \(index)") | |
| if current.doubleValue >= alert.doubleValue { | |
| let measurements = buffer.values | |
| let sum = measurements.reduce((value:0.0, elementsToIgnore:0)){sum,value in | |
| return value == 0 ? (sum.value ,sum.elementsToIgnore + 1) : (sum.value + value ,sum.elementsToIgnore) | |
| } | |
| let mid = sum.value / Double(measurements.count - sum.elementsToIgnore) | |
| print("Allert! \(name) is at \(current) which is above \(alert), average of last \(measurements.count - sum.elementsToIgnore) measurements is \(mid)") | |
| } | |
| } | |
| } | |
| numberOfTicks += 1 | |
| sleep(5) // collecting data at 0.2Hz best case | |
| } | |
| loadMachineURLs() | |
| initFiveMinutesData() | |
| while true { | |
| tick() | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment