Skip to content

Commit 77bdfcb

Browse files
committed
Add handler for partial writes, and throw exception
1 parent 958f350 commit 77bdfcb

File tree

9 files changed

+305
-54
lines changed

9 files changed

+305
-54
lines changed

AdysTech.InfluxDB.Client.Net.Test/AdysTech.InfluxDB.Client.Net.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
</Otherwise>
5252
</Choose>
5353
<ItemGroup>
54+
<Compile Include="DataGen.cs" />
5455
<Compile Include="InfluxDBClientTest.cs" />
5556
<Compile Include="Properties\AssemblyInfo.cs" />
5657
</ItemGroup>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace InfluxDB.Client.Test
8+
{
9+
static class DataGen
10+
{
11+
private static readonly Random random = new Random ();
12+
private static readonly object syncLock = new object ();
13+
14+
public static int RandomNumber(int min, int max)
15+
{
16+
lock ( syncLock )
17+
{ // synchronize
18+
return random.Next (min, max);
19+
}
20+
}
21+
22+
public static int RandomInt()
23+
{
24+
lock ( syncLock )
25+
{ // synchronize
26+
return random.Next ();
27+
}
28+
}
29+
30+
public static int RandomInt(int Max)
31+
{
32+
lock ( syncLock )
33+
{ // synchronize
34+
return random.Next (Max);
35+
}
36+
}
37+
38+
public static double RandomDouble()
39+
{
40+
lock ( syncLock )
41+
{ // synchronize
42+
return random.NextDouble ();
43+
}
44+
}
45+
46+
public static string RandomString()
47+
{
48+
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ,=/\\";
49+
var stringChars = new StringBuilder (16, 16);
50+
51+
for ( int i = 0; i < stringChars.Length; i++ )
52+
{
53+
lock ( syncLock )
54+
{
55+
stringChars.Append(chars[random.Next (chars.Length)]);
56+
}
57+
}
58+
return stringChars.ToString (); ;
59+
}
60+
61+
public static DateTime RandomDate(DateTime from, DateTime to)
62+
{
63+
lock ( syncLock )
64+
{
65+
return from.AddTicks ((long) ( random.NextDouble () * ( to.Ticks - from.Ticks ) ));
66+
}
67+
}
68+
}
69+
}

AdysTech.InfluxDB.Client.Net.Test/InfluxDBClientTest.cs

Lines changed: 113 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -218,18 +218,7 @@ public async Task TestPostDoublePointAsync()
218218
}
219219
}
220220

221-
private string GenerateRandomString()
222-
{
223-
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 ,=/\\";
224-
var stringChars = new char[16];
225-
var random = new Random ();
226221

227-
for ( int i = 0; i < stringChars.Length; i++ )
228-
{
229-
stringChars[i] = chars[random.Next (chars.Length)];
230-
}
231-
return new String (stringChars);
232-
}
233222

234223
[TestMethod]
235224
public async Task TestPostStringPointAsync()
@@ -242,7 +231,7 @@ public async Task TestPostStringPointAsync()
242231
valString.UtcTimestamp = DateTime.UtcNow;
243232
valString.Tags.Add ("TestDate", time.ToShortDateString ());
244233
valString.Tags.Add ("TestTime", time.ToShortTimeString ());
245-
valString.Fields.Add ("Stringfield", GenerateRandomString ());
234+
valString.Fields.Add ("Stringfield", @"j0,Oox7ju6lJvA0\");//DataGen.RandomString ());
246235
valString.MeasurementName = measurementName;
247236
valString.Precision = TimePrecision.Seconds;
248237
var r = await client.PostPointAsync (dbName, valString);
@@ -291,47 +280,70 @@ public async Task TestPostPointsAsync()
291280
{
292281
var client = new InfluxDBClient (influxUrl, dbUName, dbpwd);
293282
var time = DateTime.Now;
294-
var rand = new Random ();
283+
var today = DateTime.Now.ToShortDateString ();
284+
var now = DateTime.Now.ToShortTimeString ();
285+
286+
var points = new List<IInfluxDatapoint> ();
295287

296288
var valDouble = new InfluxDatapoint<double> ();
297289
valDouble.UtcTimestamp = DateTime.UtcNow;
298-
valDouble.Tags.Add ("TestDate", time.ToShortDateString ());
299-
valDouble.Tags.Add ("TestTime", time.ToShortTimeString ());
300-
valDouble.Fields.Add ("Doublefield", rand.NextDouble ());
301-
valDouble.Fields.Add ("Doublefield2", rand.NextDouble ());
290+
valDouble.Tags.Add ("TestDate", today);
291+
valDouble.Tags.Add ("TestTime", now);
292+
valDouble.Fields.Add ("Doublefield", DataGen.RandomDouble ());
293+
valDouble.Fields.Add ("Doublefield2", DataGen.RandomDouble ());
302294
valDouble.MeasurementName = measurementName;
303-
valDouble.Precision = TimePrecision.Milliseconds;
295+
valDouble.Precision = TimePrecision.Nanoseconds;
296+
points.Add (valDouble);
297+
298+
valDouble = new InfluxDatapoint<double> ();
299+
valDouble.UtcTimestamp = DateTime.UtcNow;
300+
valDouble.Tags.Add ("TestDate", today);
301+
valDouble.Tags.Add ("TestTime", now);
302+
valDouble.Fields.Add ("Doublefield", DataGen.RandomDouble ());
303+
valDouble.Fields.Add ("Doublefield2", DataGen.RandomDouble ());
304+
valDouble.MeasurementName = measurementName;
305+
valDouble.Precision = TimePrecision.Microseconds;
306+
points.Add (valDouble);
304307

305308
var valInt = new InfluxDatapoint<int> ();
306309
valInt.UtcTimestamp = DateTime.UtcNow;
307-
valInt.Tags.Add ("TestDate", time.ToShortDateString ());
308-
valInt.Tags.Add ("TestTime", time.ToShortTimeString ());
309-
valInt.Fields.Add ("Intfield", rand.Next ());
310-
valInt.Fields.Add ("Intfield2", rand.Next ());
310+
valInt.Tags.Add ("TestDate", today);
311+
valInt.Tags.Add ("TestTime", now);
312+
valInt.Fields.Add ("Intfield", DataGen.RandomInt ());
313+
valInt.Fields.Add ("Intfield2", DataGen.RandomInt ());
314+
valInt.MeasurementName = measurementName;
315+
valInt.Precision = TimePrecision.Milliseconds;
316+
points.Add (valInt);
317+
318+
valInt = new InfluxDatapoint<int> ();
319+
valInt.UtcTimestamp = DateTime.UtcNow;
320+
valInt.Tags.Add ("TestDate", today);
321+
valInt.Tags.Add ("TestTime", now);
322+
valInt.Fields.Add ("Intfield", DataGen.RandomInt ());
323+
valInt.Fields.Add ("Intfield2", DataGen.RandomInt ());
311324
valInt.MeasurementName = measurementName;
312325
valInt.Precision = TimePrecision.Seconds;
326+
points.Add (valInt);
313327

314328
var valBool = new InfluxDatapoint<bool> ();
315329
valBool.UtcTimestamp = DateTime.UtcNow;
316-
valBool.Tags.Add ("TestDate", time.ToShortDateString ());
317-
valBool.Tags.Add ("TestTime", time.ToShortTimeString ());
330+
valBool.Tags.Add ("TestDate", today);
331+
valBool.Tags.Add ("TestTime", now);
318332
valBool.Fields.Add ("Booleanfield", time.Ticks % 2 == 0);
319333
valBool.MeasurementName = measurementName;
320334
valBool.Precision = TimePrecision.Minutes;
335+
points.Add (valBool);
321336

322337
var valString = new InfluxDatapoint<string> ();
323338
valString.UtcTimestamp = DateTime.UtcNow;
324-
valString.Tags.Add ("TestDate", time.ToShortDateString ());
325-
valString.Tags.Add ("TestTime", time.ToShortTimeString ());
326-
valString.Fields.Add ("Stringfield", GenerateRandomString ());
339+
valString.Tags.Add ("TestDate", today);
340+
valString.Tags.Add ("TestTime", now);
341+
valString.Fields.Add ("Stringfield", DataGen.RandomString ());
327342
valString.MeasurementName = measurementName;
328343
valString.Precision = TimePrecision.Hours;
329-
330-
var points = new List<IInfluxDatapoint> ();
331344
points.Add (valString);
332-
points.Add (valInt);
333-
points.Add (valDouble);
334-
points.Add (valBool);
345+
346+
335347
var r = await client.PostPointsAsync (dbName, points);
336348
Assert.IsTrue (r, "PostPointsAsync retunred false");
337349
}
@@ -344,6 +356,58 @@ public async Task TestPostPointsAsync()
344356
}
345357
}
346358

359+
360+
[TestMethod]
361+
[ExpectedException (typeof (InfluxDBException))]
362+
public async Task TestPostPointsAsync_PartialWrite()
363+
{
364+
var client = new InfluxDBClient (influxUrl, dbUName, dbpwd);
365+
var time = DateTime.Now;
366+
var today = DateTime.Now.ToShortDateString ();
367+
var now = DateTime.Now.ToShortTimeString ();
368+
369+
var points = new List<IInfluxDatapoint> ();
370+
371+
372+
var valDouble = new InfluxDatapoint<double> ();
373+
valDouble.UtcTimestamp = DateTime.UtcNow;
374+
valDouble.Tags.Add ("TestDate", today);
375+
valDouble.Tags.Add ("TestTime", now);
376+
valDouble.Fields.Add ("Doublefield", DataGen.RandomDouble ());
377+
valDouble.Fields.Add ("Doublefield2", Double.NaN);
378+
valDouble.MeasurementName = measurementName;
379+
valDouble.Precision = TimePrecision.Seconds;
380+
points.Add (valDouble);
381+
382+
383+
for ( int i = 0; i < 5; i++ )
384+
{
385+
var valInt = new InfluxDatapoint<int> ();
386+
valInt.UtcTimestamp = DateTime.UtcNow.AddSeconds (-1 * DataGen.RandomInt (3600));
387+
valInt.Tags.Add ("TestDate", today);
388+
valInt.Tags.Add ("TestTime", now);
389+
valInt.Fields.Add ("Intfield", DataGen.RandomInt ());
390+
valInt.Fields.Add ("Intfield2", DataGen.RandomInt ());
391+
valInt.MeasurementName = measurementName;
392+
valInt.Precision = TimePrecision.Seconds;
393+
points.Add (valInt);
394+
}
395+
396+
valDouble = new InfluxDatapoint<double> ();
397+
valDouble.UtcTimestamp = DateTime.UtcNow;
398+
valDouble.Tags.Add ("TestDate", today);
399+
valDouble.Tags.Add ("TestTime", now);
400+
valDouble.Fields.Add ("Doublefield", DataGen.RandomDouble ());
401+
valDouble.Fields.Add ("Doublefield2", Double.NaN);
402+
valDouble.MeasurementName = measurementName;
403+
valDouble.Precision = TimePrecision.Seconds;
404+
points.Add (valDouble);
405+
406+
var r = await client.PostPointsAsync (dbName, points);
407+
Assert.IsTrue (r, "PostPointsAsync retunred false");
408+
409+
}
410+
347411
/// <summary>
348412
/// This will create 2000 objects, and posts them to Influx. Since the precision is random, many points get overwritten
349413
/// (e.g. you can have only point per hour at hour precision.
@@ -355,49 +419,49 @@ public async Task TestBachingPostPointsAsync()
355419
try
356420
{
357421
var client = new InfluxDBClient (influxUrl, dbUName, dbpwd);
358-
359-
var rand = new Random ();
422+
360423
var points = new List<IInfluxDatapoint> ();
361424

362425
var today = DateTime.Now.ToShortDateString ();
363426
var now = DateTime.Now.ToShortTimeString ();
427+
var start = DateTime.Now.AddDays (-5);
428+
var end = DateTime.Now;
364429

365-
for ( int i = 0; i < 500; i++ )
430+
for ( int i = 0; i < 5000; i++ )
366431
{
367-
var utcTime = DateTime.UtcNow;
368432
var valDouble = new InfluxDatapoint<double> ();
369-
valDouble.UtcTimestamp = utcTime;
433+
valDouble.UtcTimestamp = DataGen.RandomDate (start, end);
370434
valDouble.Tags.Add ("TestDate", today);
371435
valDouble.Tags.Add ("TestTime", now);
372-
valDouble.Fields.Add ("Doublefield", rand.NextDouble ());
373-
valDouble.Fields.Add ("Doublefield2", rand.NextDouble ());
436+
valDouble.Fields.Add ("Doublefield", DataGen.RandomDouble ());
437+
valDouble.Fields.Add ("Doublefield2", DataGen.RandomDouble ());
374438
valDouble.MeasurementName = measurementName;
375-
valDouble.Precision = (TimePrecision) ( rand.Next () % 6 ) + 1;
439+
valDouble.Precision = (TimePrecision) ( DataGen.RandomInt () % 6 ) + 1;
376440

377441
var valInt = new InfluxDatapoint<int> ();
378-
valInt.UtcTimestamp = utcTime;
442+
valInt.UtcTimestamp = DataGen.RandomDate (start, end);
379443
valInt.Tags.Add ("TestDate", today);
380444
valInt.Tags.Add ("TestTime", now);
381-
valInt.Fields.Add ("Intfield", rand.Next ());
382-
valInt.Fields.Add ("Intfield2", rand.Next ());
445+
valInt.Fields.Add ("Intfield", DataGen.RandomInt ());
446+
valInt.Fields.Add ("Intfield2", DataGen.RandomInt ());
383447
valInt.MeasurementName = measurementName;
384-
valInt.Precision = (TimePrecision) ( rand.Next () % 6 ) + 1;
448+
valInt.Precision = (TimePrecision) ( DataGen.RandomInt () % 6 ) + 1;
385449

386450
var valBool = new InfluxDatapoint<bool> ();
387-
valBool.UtcTimestamp = utcTime;
451+
valBool.UtcTimestamp = DataGen.RandomDate (start, end);
388452
valBool.Tags.Add ("TestDate", today);
389453
valBool.Tags.Add ("TestTime", now);
390454
valBool.Fields.Add ("Booleanfield", DateTime.Now.Ticks % 2 == 0);
391455
valBool.MeasurementName = measurementName;
392-
valBool.Precision = (TimePrecision) ( rand.Next () % 6 ) + 1;
456+
valBool.Precision = (TimePrecision) ( DataGen.RandomInt () % 6 ) + 1;
393457

394458
var valString = new InfluxDatapoint<string> ();
395-
valString.UtcTimestamp = utcTime;
459+
valString.UtcTimestamp = DataGen.RandomDate (start, end);
396460
valString.Tags.Add ("TestDate", today);
397461
valString.Tags.Add ("TestTime", now);
398-
valString.Fields.Add ("Stringfield", GenerateRandomString ());
462+
valString.Fields.Add ("Stringfield", DataGen.RandomString ());
399463
valString.MeasurementName = measurementName;
400-
valString.Precision = (TimePrecision) ( rand.Next () % 6 ) + 1;
464+
valString.Precision = (TimePrecision) ( DataGen.RandomInt () % 6 ) + 1;
401465

402466

403467
points.Add (valString);

AdysTech.InfluxDB.Client.Net/AdysTech.InfluxDB.Client.Net.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<Compile Include="InfluxDatapoint.cs" />
4848
<Compile Include="InfluxDBClient.cs" />
4949
<Compile Include="DataContracts\InfluxJsonTypes.cs" />
50+
<Compile Include="InfluxDBException.cs" />
5051
<Compile Include="Properties\AssemblyInfo.cs" />
5152
<Compile Include="ServiceUnavailableException.cs" />
5253
</ItemGroup>

AdysTech.InfluxDB.Client.Net/ExtensionMethods.cs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Text;
5+
using System.Text.RegularExpressions;
56
using System.Threading.Tasks;
67

78
namespace AdysTech.InfluxDB.Client.Net
@@ -19,10 +20,57 @@ public static long ToEpoch(this DateTime time, TimePrecision precision)
1920
case TimePrecision.Minutes: return (long) t.TotalMinutes;
2021
case TimePrecision.Seconds: return (long) t.TotalSeconds;
2122
case TimePrecision.Milliseconds: return (long) t.TotalMilliseconds;
22-
case TimePrecision.Microseconds: return (long) t.Ticks * ( TimeSpan.TicksPerMillisecond / 1000 );
23+
case TimePrecision.Microseconds: return (long) t.Ticks / ( TimeSpan.TicksPerMillisecond * 1000 );
2324
case TimePrecision.Nanoseconds: return (long) t.Ticks * 100; //1 tick = 100 nano sec
2425
}
2526
return 0;
2627
}
2728
}
29+
30+
public static class RegExHelper
31+
{
32+
public static List<string> ToList(this MatchCollection matches)
33+
{
34+
return matches.Cast<Match> ()
35+
// flatten to single list
36+
.SelectMany (o =>
37+
// extract captured results
38+
o.Groups.Cast<Capture> ()
39+
// don't need the pattern
40+
.Skip (1)
41+
.Select (c => c.Value)).ToList ();
42+
}
43+
}
44+
45+
public static class StringHelper
46+
{
47+
public static string Unescape(this string txt)
48+
{
49+
if ( string.IsNullOrEmpty (txt) ) { return txt; }
50+
StringBuilder retval = new StringBuilder (txt.Length);
51+
for ( int ix = 0; ix < txt.Length; )
52+
{
53+
int jx = txt.IndexOf ('\\', ix);
54+
if ( jx < 0 || jx == txt.Length - 1 ) jx = txt.Length;
55+
retval.Append (txt, ix, jx - ix);
56+
if ( jx >= txt.Length ) break;
57+
switch ( txt[jx + 1] )
58+
{
59+
case 'n': retval.Append ('\n'); break; // Line feed
60+
case 'r': retval.Append ('\r'); break; // Carriage return
61+
case 't': retval.Append ('\t'); break; // Tab
62+
case ',': retval.Append (','); break;
63+
case '"': retval.Append ('"'); break;
64+
case '=': retval.Append ('='); break;
65+
case '\\': retval.Append ('\\'); break; // Don't escape
66+
default: // Unrecognized, copy as-is
67+
retval.Append ('\\').Append (txt[jx + 1]); break;
68+
}
69+
ix = jx + 2;
70+
}
71+
72+
return retval.ToString ();
73+
}
74+
75+
}
2876
}

0 commit comments

Comments
 (0)