/// <summary> /// </summary> /// <param name="maxQueueLength">Max number of entries in timer queue.</param> /// <param name="frequency">Check the queue once every n ticks.</param> public SoftTimer(int maxQueueLength, OktofsRateController rateController) { this.rateController = rateController; queue = new SortedDictionary<long, SoftTimerEntry>(); const double dTenMillisecs = 10.0; TimersTimer = new System.Timers.Timer(dTenMillisecs); TimersTimer.Elapsed += new ElapsedEventHandler(TimersTimerCallback); TimersTimer.Interval = dTenMillisecs; TimersTimer.Enabled = true; }
public Flow( Endpoint c, Endpoint h, string inputRecord, string[] inputTokens, int inputTokensLastHeaderIndex, OktofsRateController rateController) { if (c == null && h == null) throw new ArgumentOutOfRangeException(String.Format("Flow: both endpoints cannot be null.")); this.flowId = newFlowId++; this.vmName = (c != null ? c.SidOrAccount.ToLower() : h.SidOrAccount.ToLower()); this.hypervName = (c != null ? c.FilterServer.ToLower() : h.HyperVserver.ToLower()); this.shareName = (c != null ? c.ShareOrVolume.ToLower() : null); this.storageServerName = (h != null ? h.FilterServer.ToLower() : null); this.volumeName = (h != null ? h.ShareOrVolume.ToLower() : null); this.endpointC = c; this.endpointH = h; this.inputRecord = inputRecord; this.inputTokens = inputTokens; this.inputTokensLastHeaderIndex = inputTokensLastHeaderIndex; if (String.IsNullOrEmpty(vmName) || String.IsNullOrWhiteSpace(vmName)) throw new ArgumentOutOfRangeException(String.Format("Invalid arg vmName={0}", vmName)); if (String.IsNullOrEmpty(hypervName) || String.IsNullOrWhiteSpace(hypervName)) throw new ArgumentOutOfRangeException(String.Format("Invalid arg hypervName={0}", hypervName)); if (endpointC != null && (String.IsNullOrEmpty(shareName) || String.IsNullOrWhiteSpace(shareName))) throw new ArgumentOutOfRangeException(String.Format("Invalid arg shareName={0}", shareName)); if (endpointH != null && (String.IsNullOrEmpty(storageServerName) || String.IsNullOrWhiteSpace(storageServerName))) throw new ArgumentOutOfRangeException(String.Format("Invalid arg storageServerName={0}", storageServerName)); if (endpointH != null && (String.IsNullOrEmpty(volumeName) || String.IsNullOrWhiteSpace(volumeName))) throw new ArgumentOutOfRangeException(String.Format("Invalid arg volumeName={0}", volumeName)); if (inputTokensLastHeaderIndex < 4) throw new ArgumentOutOfRangeException(String.Format("Invalid arg inputTokensLastHeaderIndex too small {0}", inputTokensLastHeaderIndex)); }
public OktofsPolicyEsses(string configFileName, string topConfigName, int slavePort) { shutdownEvent = new ManualResetEvent(false); // // initialize rate controller // parsing the config file defines VM placement and VM ordering within a traffic matrix // Random random = new Random(); uint TenantId = (uint)random.Next(1, int.MaxValue); // min P of collision at slaves. rateController = new OktofsRateController(this, TenantId, slavePort); InitBandwidthWeights(BWWeightsConfigFile); //initialize the bandwidth weights from the appropriate config file string[] validInputRecords = new string[] { "D-VM-FILE-VOL", "CD-VM-FILE-VOL", "CH-VM-FILE-VOL", "C-VM-SHARE-VOL", "H-VM-SHARE-VOL", "CH-VM-SHARE-VOL" }; listFlows = rateController.InitListFlows(configFileName, validInputRecords); fileCaches = new Dictionary<string, EssesFileCacheContext>(); //Initialize some controller-side context about each flow's cache and the file caches they belong to based on the input tokens stored when flows were created foreach (Flow flow in listFlows) { UInt64 fileCacheSize = Convert.ToUInt64(flow.InputTokens[9]); string flowTenantID = flow.InputTokens[12]; if (!this.fileCaches.ContainsKey(flowTenantID)) { this.fileCaches.Add(flowTenantID, new EssesFileCacheContext(fileCacheSize)); } this.fileCaches[flowTenantID].flows.Add(flow); //Add this flow to the context for this file cache UInt64 flowCacheSizeAllocated = Convert.ToUInt64(flow.InputTokens[5]); CacheWritePolicy writePolicy = 0; CacheWriteBuffer cacheWrites = 0; switch (flow.InputTokens[7]) { case "write-through": writePolicy = CacheWritePolicy.WriteThrough; break; } switch (flow.InputTokens[8]) { case "noCacheWrites": cacheWrites = CacheWriteBuffer.noCache; break; case "CacheWrites": cacheWrites = CacheWriteBuffer.Cache; break; } EssesFlowCacheContext flowContext = new EssesFlowCacheContext(flow, flowCacheSizeAllocated, writePolicy, cacheWrites, flow.InputTokens[11], flowTenantID); flow.Context = flowContext; //flowContext.minFlowGuarantee = Convert.ToUInt64(flow.InputTokens[10]); flowContext.guaranteedE2EBW = Convert.ToUInt64(flow.InputTokens[13]); } // // ask Rate Controller to create the queues on the remote servers. // rateController.InstallFlows(); // // At this point the Rate Controller is connected to the rate slaves and the // minifilter drivers are configured with queues. The minifilters will not enforce // rate limits until we install the RAPs, which is done in the Start() routine. // }
private const int OKTO_FLT_INFO_BUFF_BYTE_LEN = 256; // ref oktofsuser.h #endregion Fields #region Methods public static MessageStatsReplyDelta CreateFromNetBytes( byte[] buffer, int offset, Connection conn, OktofsRateController rateController) { // // Get header info and lengths of the Device and Stats arrays. // MessageStatsReplyDelta msg = new MessageStatsReplyDelta(); msg.Length = (uint)Utils.Int32FromNetBytes(buffer, offset); offset += 4; msg.SeqNo = (uint)Utils.Int32FromNetBytes(buffer, offset); offset += 4; msg.MessageType = buffer[offset++]; msg.Result = (uint)Utils.Int32FromNetBytes(buffer, offset); offset += 4; msg.IntervalUSecs = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; msg.CountDeviceInfo = (ushort)Utils.Int16FromNetBytes(buffer, offset); offset += 2; msg.CountFlowStats = (ushort)Utils.Int16FromNetBytes(buffer, offset); offset += 2; // // Get the array of Device stats. // char[] charsToTrim = { '\0' }; for (int i = 0; i < msg.CountDeviceInfo; i++) { string deviceName = UnicodeEncoding.Unicode.GetString(buffer, offset, (OKTO_FLT_INFO_BUFF_BYTE_LEN + 2)); offset += (OKTO_FLT_INFO_BUFF_BYTE_LEN + 2); deviceName = deviceName.TrimEnd(charsToTrim); Device device = rateController.FindOrCreateDevice(conn.HostName, deviceName); lock (device) { device.AveInFlightTick.Read.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveInFlightTick.Read.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveInFlightTick.Write.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveInFlightTick.Write.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveInFlightEvent.Read.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveInFlightEvent.Read.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveInFlightEvent.Write.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveInFlightEvent.Write.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenTick.Read.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenTick.Read.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenTick.Write.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenTick.Write.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenEvent.Read.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenEvent.Read.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenEvent.Write.Iops = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; device.AveQueueLenEvent.Write.Tokens = (ulong)Utils.Int64FromNetBytes(buffer, offset); offset += 8; } } // // Get the array of FlowStats. // for (int i = 0; i < msg.CountFlowStats; i++) { ushort idxRap = (ushort)Utils.Int16FromNetBytes(buffer, offset); offset += 2; FlowStats flowStats = FlowStats.CreateFromNetBytes(buffer, offset, out offset); msg.dictFlowStats.Add(idxRap, flowStats); } return msg; }