public void ShouldCreateDelayedAttribute() { var attr = new DelayedAttribute(typeof(FakeDto), count: 1); attr.Type.Should().Be(typeof(FakeDto)); attr.KeyPropertyFunc(new FakeDto()).Should().BeEmpty(); }
public void ShouldRejectInvalidDtoType() { var attr = new DelayedAttribute(typeof(FakeDtoWithKeyProperties), count: 1); var e = Record.Exception(() => attr.KeyPropertyFunc(new FakeDto())); e.Should().BeOfType <ArgumentException>(); }
public void ShouldCreateKeyProperties() { var attr = new DelayedAttribute(typeof(FakeDtoWithKeyProperties), count: 1); attr.Type.Should().Be(typeof(FakeDtoWithKeyProperties)); attr.KeyPropertyFunc(new FakeDtoWithKeyProperties { Property = "test" }).Should().Contain("test"); }
private bool ShouldExecute(DelayedAttribute attr, int?size, TimeSpan?age) { if (attr.Count.HasValue && size.HasValue) { if (attr.Count.Value <= size) { return(true); } } if (attr.Delay.HasValue && age.HasValue) { return(TimeSpan.FromMilliseconds(attr.Delay.Value) <= age); } return(false); }
private async Task InvokeDelayedChannel(IDelayedChannel channel, string channelKey, string specificKey, DelayedAttribute attr, MessageHandler handler, IInvokeHandlerContext context) { var msgs = await channel.Pull(channelKey, key : specificKey, max : attr.Count).ConfigureAwait(false); if (!msgs.Any()) { Logger.Write(LogLevel.Debug, () => $"No delayed events found on channel [{channelKey}] specific key [{specificKey}]"); return; } var idx = 0; var count = msgs.Count(); Invokes.Mark(); InvokeSize.Update(msgs.Count()); Logger.Write(LogLevel.Info, () => $"Starting invoke handle {count} times channel key [{channelKey}] specific key [{specificKey}]"); using (var ctx = InvokeTime.NewContext()) { foreach (var msg in msgs.Cast <DelayedMessage>()) { idx++; Logger.Write(LogLevel.Debug, () => $"Invoking handle {idx}/{count} times channel key [{channelKey}] specific key [{specificKey}]"); await handler.Invoke(msg.Message, context).ConfigureAwait(false); } if (ctx.Elapsed > TimeSpan.FromSeconds(5)) { SlowLogger.Write(LogLevel.Warn, () => $"Bulk invoking {count} times on channel key [{channelKey}] specific key [{specificKey}] took {ctx.Elapsed.TotalSeconds} seconds!"); } Logger.Write(LogLevel.Info, () => $"Bulk invoking {count} times on channel key [{channelKey}] specific key [{specificKey}] took {ctx.Elapsed.TotalMilliseconds} ms!"); } Logger.Write(LogLevel.Info, () => $"Finished invoke handle {count} times channel key [{channelKey}] specific key [{specificKey}]"); }
private async Task InvokeDelayedChannel(IDelayedChannel channel, string channelKey, string specificKey, DelayedAttribute attr, MessageHandler handler, IInvokeHandlerContext context) { var msgs = await channel.Pull(channelKey, key : specificKey, max : attr.Count).ConfigureAwait(false); var messages = msgs as IDelayedMessage[] ?? msgs.ToArray(); var count = messages.Length; using (var ctx = _metrics.Begin("Bulk Messages Time")) { switch (attr.Mode) { case DeliveryMode.Single: foreach (var idx in Enumerable.Range(0, messages.Length)) { await handler.Invoke(messages[idx].Message, context).ConfigureAwait(false); } break; case DeliveryMode.First: await handler.Invoke(messages[0].Message, context).ConfigureAwait(false); break; case DeliveryMode.Last: await handler.Invoke(messages[messages.Length - 1].Message, context).ConfigureAwait(false); break; case DeliveryMode.FirstAndLast: await handler.Invoke(messages[0].Message, context).ConfigureAwait(false); await handler.Invoke(messages[messages.Length - 1].Message, context).ConfigureAwait(false); break; } if (ctx.Elapsed > TimeSpan.FromSeconds(5)) { SlowLogger.InfoEvent("Invoked", "{Count} messages channel [{Channel:l}] key [{Key:l}] took {Milliseconds} ms", count, channelKey, specificKey, ctx.Elapsed.TotalMilliseconds); } Logger.DebugEvent("Invoked", "{Count} messages channel [{Channel:l}] key [{Key:l}] took {Milliseconds} ms", count, channelKey, specificKey, ctx.Elapsed.TotalMilliseconds); } }
private async Task InvokeDelayedChannel(IDelayedChannel channel, string channelKey, string specificKey, DelayedAttribute attr, MessageHandler handler, IInvokeHandlerContext context) { var msgs = await channel.Pull(channelKey, key : specificKey, max : attr.Count).ConfigureAwait(false); var messages = msgs as IDelayedMessage[] ?? msgs.ToArray(); if (!messages.Any()) { Logger.Write(LogLevel.Debug, () => $"No delayed events found on channel [{channelKey}] specific key [{specificKey}]"); return; } var count = messages.Length; Logger.Write(LogLevel.Debug, () => $"Starting invoke handle {count} times channel key [{channelKey}] specific key [{specificKey}]"); using (var ctx = _metrics.Begin("Bulk Messages Time")) { foreach (var idx in Enumerable.Range(0, messages.Length)) { Logger.Write(LogLevel.Debug, () => $"Invoking handle {idx}/{count} times channel key [{channelKey}] specific key [{specificKey}]"); await handler.Invoke(messages[idx].Message, context).ConfigureAwait(false); } if (ctx.Elapsed > TimeSpan.FromSeconds(5)) { SlowLogger.Write(LogLevel.Warn, () => $"Bulk invoking {count} times on channel key [{channelKey}] specific key [{specificKey}] took {ctx.Elapsed.TotalSeconds} seconds!"); } Logger.Write(LogLevel.Info, () => $"Bulk invoking {count} times on channel key [{channelKey}] specific key [{specificKey}] took {ctx.Elapsed.TotalMilliseconds} ms!"); } }
/// <inheritdoc /> public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // Retrieve attributes List <ConditionalAttribute> conditionalAttributes = new List <ConditionalAttribute>(); // ColorUsageAttribute colorUsageAttribute = null; #if UNITY_5_3_OR_NEWER DelayedAttribute delayedAttribute = null; #endif MultilineAttribute multilineAttribute = null; TextAreaAttribute textAreaAttribute = null; RangeAttribute rangeAttribute = null; ReadOnlyAttribute readOnlyAttribute = null; object[] customAttributes = fieldInfo.GetCustomAttributes(false); for (int i = 0; i < customAttributes.Length; i++) { if (customAttributes[i] is ConditionalAttribute) { conditionalAttributes.Add((ConditionalAttribute)customAttributes[i]); } // else if (customAttributes[i] is ColorUsageAttribute) // { // colorUsageAttribute = (ColorUsageAttribute)customAttributes[i]; // } #if UNITY_5_3_OR_NEWER else if (customAttributes[i] is DelayedAttribute) { delayedAttribute = (DelayedAttribute)customAttributes[i]; } #endif else if (customAttributes[i] is MultilineAttribute) { multilineAttribute = (MultilineAttribute)customAttributes[i]; } else if (customAttributes[i] is TextAreaAttribute) { textAreaAttribute = (TextAreaAttribute)customAttributes[i]; } else if (customAttributes[i] is RangeAttribute) { rangeAttribute = (RangeAttribute)customAttributes[i]; } else if (customAttributes[i] is ReadOnlyAttribute) { readOnlyAttribute = (ReadOnlyAttribute)customAttributes[i]; } else if (customAttributes[i] is TooltipAttribute || customAttributes[i] is SerializeField || customAttributes[i] is NonSerializedAttribute) { // Ignored attributes } else { Debug.LogWarning("ConditionalPropertyDrawer needs implementation for type " + customAttributes[i].ToString()); } } int conditionCount = 0; for (int i = 0; i < conditionalAttributes.Count; i++) { if (conditionalAttributes[i].Conditions != null) { conditionCount += conditionalAttributes[i].Conditions.Length; } } ConditionalAttribute.Condition[] conditions = new ConditionalAttribute.Condition[conditionCount]; int index = 0; for (int i = 0; i < conditionalAttributes.Count; i++) { if (conditionalAttributes[i].Conditions != null) { ConditionalAttribute.Condition[] conds = conditionalAttributes[i].Conditions; for (int j = 0; j < conds.Length; j++) { conditions[index++] = conds[j]; } } } Attribute.Show = true; try { Attribute.Show = ShouldShow(property, conditions); } catch (Exception e) { Debug.LogException(e); } if (Attribute.Show) { if (readOnlyAttribute != null) { GUI.enabled = false; } // Implementations obtained through inspection #if UNITY_5_3_OR_NEWER if (delayedAttribute != null) { PropertyDrawer propertyDrawer = GetPropertyDrawer("UnityEditor.DelayedDrawer,UnityEditor"); propertyDrawer.OnGUI(position, property, label); } else #endif /* if (colorUsageAttribute != null) * { * * EditorGUI.BeginChangeCheck(); #if UNITY_5_3_OR_NEWER * ColorPickerHDRConfig hdrConfig = new ColorPickerHDRConfig( * colorUsageAttribute.minBrightness, colorUsageAttribute.maxBrightness, * colorUsageAttribute.minExposureValue, colorUsageAttribute.maxExposureValue); * Color color = EditorGUI.ColorField(position, label, property.colorValue, * true, colorUsageAttribute.showAlpha, colorUsageAttribute.hdr, hdrConfig); #else * Color color = EditorGUI.ColorField(position, label, property.colorValue); #endif * if (EditorGUI.EndChangeCheck()) * { * property.colorValue = color; * } * } * else */ if (multilineAttribute != null) { PropertyDrawer propertyDrawer = GetPropertyDrawer("UnityEditor.MultilineDrawer,UnityEditor"); propertyDrawer.OnGUI(position, property, label); } else if (textAreaAttribute != null) { PropertyDrawer propertyDrawer = GetPropertyDrawer("UnityEditor.TextAreaDrawer,UnityEditor"); propertyDrawer.OnGUI(position, property, label); } else if (rangeAttribute != null) { if (property.propertyType == SerializedPropertyType.Float) { EditorGUI.Slider(position, property, rangeAttribute.min, rangeAttribute.max, label); } else if (property.propertyType == SerializedPropertyType.Integer) { EditorGUI.IntSlider(position, property, (int)rangeAttribute.min, (int)rangeAttribute.max, label); } else { EditorGUI.LabelField(position, label.text, "Use Range with float or int."); } } else { EditorGUI.PropertyField(position, property, label, false); } if (readOnlyAttribute != null) { GUI.enabled = true; } } }