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

Fix #82: QueryMultiSeriesAsync should return "partial" #89

Merged
merged 6 commits into from
Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
## v0.11.0 [02/01/2020]

### Release Notes
Option to add a rentention policy with infinite duration - Thanks to @jasase
Handle truncated responses due to "max-row-limit", (flag "partial=true"). Thanks to @tbraun-hk

### Bugfixes

- [#82](https://github.com/AdysTech/InfluxDB.Client.Net/issues/82): QueryMultiSeriesAsync should return "partial" if responses are truncated by InfluxDB
- [#83](https://github.com/AdysTech/InfluxDB.Client.Net/issues/83): Create Infinite Retention Policy

## v0.9.0 [10/12/2019]

### Release Notes
Add MeasurementHierarchy to IInfluxDatabase, SeriesCount and PointsCount properties to IInfluxMeasurement
Now calling `GetInfluxDBStructureAsync` populates the structure with retention policies, and also gives the unique series and point counts for each of the measurements
Allow for deleting/dropping the Influx database by calling `DropDatabaseAsync`, allow delete entire measurement via `DropMeasurementAsync` as well as specific data points with and where clause using `TestDeletePointsAsync`

### Bugfixes

- [#72](https://github.com/AdysTech/InfluxDB.Client.Net/issues/72): Performance improvements
- [#69](https://github.com/AdysTech/InfluxDB.Client.Net/issues/69): easiest way to count the entries in the measurement
- [#67](https://github.com/AdysTech/InfluxDB.Client.Net/issues/67): delete an existing database
- [#41](https://github.com/AdysTech/InfluxDB.Client.Net/issues/41): DELETE FROM {Measurement} WHERE

## v0.9.0 [10/12/2019]

### Release Notes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Product>AdysTech.InfluxDB.Client.Net</Product>
<Company>AdysTech</Company>
<Authors>AdysTech;mvadu</Authors>
<Version>0.9.0.0</Version>
<Version>0.11.1.0</Version>
<PackageId>AdysTech.InfluxDB.Client.Net.Core</PackageId>
<Copyright>© AdysTech 2016-2019</Copyright>
<PackageProjectUrl>https://github.com/AdysTech/InfluxDB.Client.Net</PackageProjectUrl>
Expand All @@ -29,8 +29,8 @@ It currently supports
10. Chunking Support in queries
11. Drop databases, measurements or points
12. Get series count or points count for a measurement</PackageReleaseNotes>
<AssemblyVersion>0.10.0.0</AssemblyVersion>
<FileVersion>0.10.0.0</FileVersion>
<AssemblyVersion>0.11.1.0</AssemblyVersion>
<FileVersion>0.11.1.0</FileVersion>
<PackageTags>InfluxDB Influx TSDB TimeSeries InfluxData Chunking retention RetentionPolicy</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/AdysTech.InfluxDB.Client.Net/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.10.0.0")]
[assembly: AssemblyFileVersion("0.10.0.0")]
[assembly: AssemblyVersion("0.11.1.0")]
[assembly: AssemblyFileVersion("0.11.1.0")]
12 changes: 9 additions & 3 deletions src/DataStructures/InfluxDBClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ public async Task<List<IInfluxSeries>> QueryMultiSeriesAsync(string dbName, stri
{
var results = new List<IInfluxSeries>();
var rawResult = JsonConvert.DeserializeObject<InfluxResponse>(await response.Content.ReadAsStringAsync());
var partialResult = rawResult.Results?.Any(r => r.Partial == true);

if (rawResult?.Results?.Count > 1)
throw new ArgumentException("The query is resulting in a format, which is not supported by this method yet");
Expand All @@ -582,7 +583,7 @@ public async Task<List<IInfluxSeries>> QueryMultiSeriesAsync(string dbName, stri
{
foreach (var series in rawResult?.Results[0]?.Series)
{
InfluxSeries result = GetInfluxSeries(precision, series);
InfluxSeries result = GetInfluxSeries(precision, series, partialResult);
results.Add(result);
}
}
Expand Down Expand Up @@ -629,11 +630,12 @@ public async Task<List<IInfluxSeries>> QueryMultiSeriesAsync(string dbName, stri
{
var str = await reader.ReadLineAsync();
var rawResult = JsonConvert.DeserializeObject<InfluxResponse>(str);
var partialResult = rawResult?.Results?.Any(r => r.Partial == true);
if (rawResult?.Results[0]?.Series != null)
{
foreach (var series in rawResult?.Results[0]?.Series)
{
InfluxSeries result = GetInfluxSeries(precision, series);
InfluxSeries result = GetInfluxSeries(precision, series, partialResult);
results.Add(result);
}
}
Expand All @@ -650,9 +652,11 @@ public async Task<List<IInfluxSeries>> QueryMultiSeriesAsync(string dbName, stri
/// </summary>
/// <param name="precision"></param>
/// <param name="series"></param>
/// <param name="partialResult"></param>
/// <param name="SafePropertyNames">If true the first letter of each property name will be Capital, making them safer to use in C#</param>
/// <returns></returns>
private static InfluxSeries GetInfluxSeries(TimePrecision precision, Series series, bool SafePropertyNames = true)
private static InfluxSeries GetInfluxSeries(TimePrecision precision, Series series, bool? partialResult,
bool SafePropertyNames = true)
{
var result = new InfluxSeries()
{
Expand All @@ -661,6 +665,8 @@ private static InfluxSeries GetInfluxSeries(TimePrecision precision, Series seri

result.SeriesName = series.Name;
result.Tags = series.Tags;
result.Partial = partialResult ?? false;

var entries = new List<dynamic>();
for (var row = 0; row < series?.Values?.Count; row++)
{
Expand Down
7 changes: 7 additions & 0 deletions src/DataStructures/InfluxSeries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,12 @@ public class InfluxSeries : IInfluxSeries
/// The objects will have columns as Peoperties with their current values
/// </summary>
public IReadOnlyList<dynamic> Entries { get; internal set; }

/// <summary>
/// True if the influx query was answered with a partial response due to e.g. exceeding a configured
/// max-row-limit in the InfluxDB. As we don't know which series was truncated by InfluxDB, all series
/// of the response will be flagged with Partial=true.
/// </summary>
public bool Partial { get; set; }
}
}
7 changes: 7 additions & 0 deletions src/Interfaces/IInfluxSeries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,12 @@ public interface IInfluxSeries
/// Dictionary of tags, and their respective values.
/// </summary>
IReadOnlyDictionary<string, string> Tags { get; }

/// <summary>
/// True if the influx query was answered with a partial response due to e.g. exceeding a configured
/// max-row-limit in the InfluxDB. As we don't know which series was truncated by InfluxDB, all series
/// of the response will be flagged with Partial=true.
/// </summary>
bool Partial { get; set; }
}
}
13 changes: 9 additions & 4 deletions tests/InfluxDB.Client.Net.TestSetup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
#executed before CreateDatabase test
#
##################################################################################################
Stop-Process -name influxd -Force -ErrorAction SilentlyContinue

if( $null -ne (Get-Process -name influxd -ErrorAction SilentlyContinue)){
Stop-Process -name influxd -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 10
}

$nightlies = $true
if ($nightlies -ne $true) {
Expand Down Expand Up @@ -47,8 +49,8 @@ else {
}


$cred = Get-Content .\tests\cred.json -Encoding UTF8 | ConvertFrom-Json
#$cred = @{User="admin"; Password="test123$€₹#₳₷ȅ"}
#$cred = Get-Content .\tests\cred.json -Encoding UTF8 | ConvertFrom-Json
$cred = @{User="admin"; Password="test123$€₹#₳₷ȅ"}
$authHeader = @{Authorization = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($cred.User):$($cred.Password)")))"}

#$x = 7z e $archivepath -o"$env:Temp/influxdb" -y
Expand Down Expand Up @@ -89,6 +91,9 @@ $proc.Kill()
write-output "enable auth in config"
(get-content $influxconf | foreach-object {$_ -replace "auth-enabled = false" , "auth-enabled = true" }) | Set-Content $influxconf

write-output "max-row-limit to 100000"
(get-content $influxconf | foreach-object {$_ -replace "[# ]?\s*max-row-limit = 0" , " max-row-limit = 100000" }) | Set-Content $influxconf

write-output "start influxdb with auth enabled"
$proc = Start-Process -FilePath $influxd -ArgumentList "-config $influxconf" -PassThru
Start-Sleep -s 5
Expand Down
52 changes: 52 additions & 0 deletions tests/InfluxDBClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -830,6 +830,58 @@ public async Task TestPerformance()
}
}

/// <summary>
/// You need to configure your test InfluxDB with a max-row-limit of 100.000 for this test to succeed!
/// </summary>
/// <returns></returns>
[TestMethod, TestCategory("Perf")]
public async Task TestPartialResponseBecauseOfMaxRowLimit()
{
try
{
var client = new InfluxDBClient(influxUrl, dbUName, dbpwd);

var points = new List<IInfluxDatapoint>();

var today = DateTime.Now.ToShortDateString();
var now = DateTime.UtcNow;
var nowString = DateTime.Now.ToShortTimeString();
var measurement = "Partialtest";

for (int i = 0; i < 200000; i++)
{
var valMixed = new InfluxDatapoint<InfluxValueField>();
valMixed.Tags.Add("TestDate", today);
valMixed.Tags.Add("TestTime", nowString);
valMixed.UtcTimestamp = now + TimeSpan.FromMilliseconds(i * 100);
valMixed.Fields.Add("Open", new InfluxValueField(DataGen.RandomDouble()));
valMixed.Fields.Add("High", new InfluxValueField(DataGen.RandomDouble()));
valMixed.Fields.Add("Low", new InfluxValueField(DataGen.RandomDouble()));
valMixed.Fields.Add("Close", new InfluxValueField(DataGen.RandomDouble()));
valMixed.Fields.Add("Volume", new InfluxValueField(DataGen.RandomDouble()));

valMixed.MeasurementName = measurement;
valMixed.Precision = TimePrecision.Nanoseconds;
points.Add(valMixed);
}


Assert.IsTrue(await client.PostPointsAsync(dbName, points, 25000), "PostPointsAsync retunred false");

var r = await client.QueryMultiSeriesAsync(dbName, "SELECT * FROM Partialtest");
Assert.IsTrue(r.All(s => s.Partial), "Not all influx series returned by the query contained the flag 'partial=true'");

r = await client.QueryMultiSeriesAsync(dbName, "SELECT * FROM Partialtest limit 50000");
Assert.IsTrue(!r.Any(s => s.Partial), "At least one of the influx series returned by the query contained the flag 'partial=true'");
}
catch (Exception e)
{

Assert.Fail($"Unexpected exception of type {e.GetType()} caught: {e.Message}");
return;
}
}

[TestMethod, TestCategory("Drop")]
public async Task TestDropDatabaseAsync()
{
Expand Down