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

5.3 to 5.4 merge #14552

Merged
merged 38 commits into from Jul 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
38bd335
Bump moment from 2.29.2 to 2.29.4 in /src/Raven.Studio
dependabot[bot] Jul 13, 2022
e6cb652
RavenDB-17010 - cloning only the relevant fields that needs to be cloned
grisha-kotler Jul 13, 2022
bafdf82
RavenDB-18862 - allow to take samples of the cpu threads
grisha-kotler Jul 13, 2022
3432ee9
RavenDB-18619 - IncludeExplanations doesn't work correctly
shaharhikri Jul 3, 2022
9c09d96
RavenDB-18619 - Fix Timing and changed Explanation included flag name
shaharhikri Jul 12, 2022
86d63c5
RavenDB-18619 - Make ShouldBeIncluded internal
shaharhikri Jul 13, 2022
6e8cf34
RavenDB-17903 - Can't operate new bulk insert on one node database if…
shaharhikri Jul 12, 2022
c5ab34e
RavenDB-17903 - 2 Tests added
shaharhikri Jul 13, 2022
4b83808
RavenDB-17903 - Added debug assert for serverNode url
shaharhikri Jul 13, 2022
e79b433
RavenDB-17903 - Added 1 Should_Throw_AllTopologyNodesDownException test
shaharhikri Jul 13, 2022
4025308
RavenDB-18676 - add top 5 threads to the memory info
grisha-kotler Jun 15, 2022
7462280
RavenDB-18676 - add the calculated available memory
grisha-kotler Jun 15, 2022
945d448
RavenDB-18676 - log every 5 seconds
grisha-kotler Jul 5, 2022
e3f9595
RavenDB-18676 - enhance the error message
grisha-kotler Jul 5, 2022
5fc2984
RavenDB-18676 - use StringBuilder, less allocations
grisha-kotler Jul 5, 2022
96c43cc
RavenDB-18676 - reduce allocations
grisha-kotler Jul 6, 2022
cf62bfb
RavenDB-18676 - reduce allocations
grisha-kotler Jul 7, 2022
2ad6bd5
RavenDB-18676 - add missing comma and bracket
grisha-kotler Jul 13, 2022
595c5bd
RavenDB-18921 : avoid holding the read transaction in cluster observe…
aviv86 Jul 12, 2022
9dd3053
RavenDB-18921 : adjust relevant tests due to changes made in ClusterO…
aviv86 Jul 12, 2022
05158d7
RavenDB-18921 : change expected exception type in catch clause (see h…
aviv86 Jul 12, 2022
2da780d
RavenDB-18908 Support multiple result set in map-reduce visualize
ayende Jul 7, 2022
ab6b135
RavenDB-18920 - Ability to download logs
grisha-kotler Jul 8, 2022
50fec3c
RavenDB-18920 - address pr comments
grisha-kotler Jul 11, 2022
444e346
RavenDB-18920 - allow to download by date
grisha-kotler Jul 11, 2022
d9e1b22
RavenDB-18920 Download logs (in Admin Logs view)
Danielle9897 Jul 12, 2022
09f628d
RavenDB-18920 Fix review comments
Danielle9897 Jul 13, 2022
1a4176b
RavenDB-18920 - use only the file stream
grisha-kotler Jul 14, 2022
d5f1ff5
RavenDB-18957 Adds support for linq queries using a dictionary entit…
a-haddaji-neoventive Jul 4, 2022
54d46cb
RavenDB-18957 Adds support for linq queries using a dictionary entity…
a-haddaji-neoventive Jul 5, 2022
038e009
RavenDB-18957 Unit test using query from the ticket.
a-haddaji-neoventive Jul 7, 2022
85a3eab
RavenDB-18957 Safe casting & Removing nullables from tests.
maciejaszyk Jul 14, 2022
4896e2e
RavenDB-18862 No need to divide by activeCores
haludi Jul 14, 2022
aa5e7d8
RavenDB-18921 - formatting of messages in the decision log
grisha-kotler Jul 14, 2022
4654f5e
RavenDB-18956 Fixing unexpected error in indexing thread which effect…
arekpalinski Jul 14, 2022
b120a9b
Merge branch 'v5.2' of https://github.com/ravendb/ravendb into v5.3
ppekrol Jul 14, 2022
bf1d1d4
Merge pull request #14551 from ppekrol/v5.3
ppekrol Jul 14, 2022
03a18f5
Merge branch 'v5.3' of https://github.com/ravendb/ravendb into v5.4
ppekrol Jul 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/Raven.Client/Documents/Linq/LinqPathProvider.cs
Expand Up @@ -80,10 +80,19 @@ public Result GetPath(Expression expression, bool isFilterActive = false)

if (callExpression.Method.Name == "get_Item")
{
var parent = GetPath(callExpression.Object);

var itemKey = GetValueFromExpression(callExpression.Arguments[0], callExpression.Method.GetParameters()[0].ParameterType).ToString();

if (callExpression.Object?.NodeType == ExpressionType.Parameter)
{
return new Result
{
MemberType = callExpression.Method.ReturnType,
IsNestedPath = false,
Path = itemKey
};
}

var parent = GetPath(callExpression.Object);
return new Result
{
MemberType = callExpression.Method.ReturnType,
Expand Down
Expand Up @@ -510,6 +510,8 @@ private bool IsMemberAccessForQuerySource(Expression node)
}
if (node.NodeType == ExpressionType.Parameter)
return true;
if (node.NodeType == ExpressionType.Call && node is MethodCallExpression callExpressionNode && callExpressionNode.Method.Name == "get_Item" && callExpressionNode.Object?.NodeType == ExpressionType.Parameter)
return true;
if (node.NodeType != ExpressionType.MemberAccess)
return false;
var memberExpression = ((MemberExpression)node);
Expand Down
Expand Up @@ -6,6 +6,8 @@ public class Explanations
{
private Dictionary<string, string[]> _explanations;

internal bool ShouldBeIncluded { get; set; } = false;

public string[] GetExplanations(string key)
{
if (_explanations.TryGetValue(key, out var results) == false)
Expand Down
Expand Up @@ -6,7 +6,7 @@ namespace Raven.Client.Documents.Session
{
public abstract partial class AbstractDocumentQuery<T, TSelf>
{
protected Explanations Explanations;
protected Explanations Explanations = new Explanations();

protected ExplanationToken ExplanationToken;

Expand All @@ -17,7 +17,9 @@ public void IncludeExplanations(ExplanationOptions options, out Explanations exp

var optionsParameterName = options != null ? AddQueryParameter(options) : null;
ExplanationToken = ExplanationToken.Create(optionsParameterName);
Explanations = explanations = new Explanations();
Explanations.ShouldBeIncluded = true;
explanations = Explanations;
}

}
}
6 changes: 4 additions & 2 deletions src/Raven.Client/Documents/Session/AbstractDocumentQuery.cs
Expand Up @@ -1484,8 +1484,10 @@ private void UpdateStatsHighlightingsAndExplanations(QueryResult queryResult)
{
QueryStats.UpdateQueryStats(queryResult);
QueryHighlightings.Update(queryResult);
Explanations?.Update(queryResult);
QueryTimings?.Update(queryResult);
if (Explanations.ShouldBeIncluded)
Explanations.Update(queryResult);
if (QueryTimings.ShouldBeIncluded)
QueryTimings.Update(queryResult);
}

private void BuildSelect(StringBuilder writer)
Expand Down
14 changes: 11 additions & 3 deletions src/Raven.Client/Http/NodeSelector.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Raven.Client.Exceptions;
using Raven.Client.Exceptions.Database;
Expand Down Expand Up @@ -66,12 +67,19 @@ public bool OnUpdateTopology(Topology topology, bool forceUpdate = false)
var state = _state;
var stateFailures = state.Failures;
var serverNodes = state.Nodes;
var len = Math.Min(serverNodes.Count, stateFailures.Length);
for (var i = 0; i < len; i++)

Debug.Assert(serverNodes.Count == stateFailures.Length, $"Expected equals {serverNodes.Count}, but got {stateFailures.Length}");

if (serverNodes.Count == 1 && serverNodes[0].ClusterTag == nodeTag) // If this is a cluster with 1 node return it without checking it's failure.
return (0, serverNodes[0]);

for (var i = 0; i < serverNodes.Count; i++)
{
if (serverNodes[i].ClusterTag == nodeTag)
{
if (stateFailures[i] == 0 && string.IsNullOrEmpty(serverNodes[i].Url) == false)
Debug.Assert(string.IsNullOrEmpty(serverNodes[i].Url) == false, $"Expected serverNodes Url not null or empty but got: \'{serverNodes[i].Url}\'");

if (stateFailures[i] == 0)
return (i, serverNodes[i]);

throw new RequestedNodeUnavailableException($"Requested node {nodeTag} currently unavailable, please try again later.");
Expand Down
10 changes: 8 additions & 2 deletions src/Raven.Server/Dashboard/ThreadsInfo.cs
Expand Up @@ -9,18 +9,23 @@ namespace Raven.Server.Dashboard
{
public class ThreadsInfo : IDynamicJson
{
private readonly int? _take;

public DateTime Date => SystemTime.UtcNow;

public SortedSet<ThreadInfo> List { get; }

public double CpuUsage { get; set; }

public double ProcessCpuUsage { get; set; }

public long ActiveCores { get; set; }

public long ThreadsCount => List.Count;

public ThreadsInfo()
public ThreadsInfo(int? take)
{
_take = take;
List = new SortedSet<ThreadInfo>(new ThreadsInfoComparer());
}

Expand All @@ -47,9 +52,10 @@ public DynamicJsonValue ToJson()
{
[nameof(Date)] = Date,
[nameof(CpuUsage)] = CpuUsage,
[nameof(ProcessCpuUsage)] = ProcessCpuUsage,
[nameof(ActiveCores)] = ActiveCores,
[nameof(ThreadsCount)] = ThreadsCount,
[nameof(List)] = new DynamicJsonArray(List.Select(x => x.ToJson()))
[nameof(List)] = new DynamicJsonArray(List.Take(_take ?? int.MaxValue).Select(x => x.ToJson()))
};
}
}
Expand Down
72 changes: 71 additions & 1 deletion src/Raven.Server/Documents/Handlers/Admin/AdminLogsHandler.cs
@@ -1,12 +1,19 @@
using System.Threading.Tasks;
using System;
using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;
using Raven.Client.ServerWide.Operations.Logs;
using Raven.Server.Indexing;
using Raven.Server.Json;
using Raven.Server.Routing;
using Raven.Server.ServerWide;
using Raven.Server.Web;
using Sparrow;
using Sparrow.Json;
using Sparrow.Json.Parsing;
using Sparrow.Logging;
using Sparrow.Server.Platform.Posix;
using Sparrow.Utils;

namespace Raven.Server.Documents.Handlers.Admin
{
Expand Down Expand Up @@ -77,5 +84,68 @@ public async Task RegisterForLogs()
await LoggingSource.Instance.Register(socket, context, ServerStore.ServerShutdown);
}
}

[RavenAction("/admin/logs/download", "GET", AuthorizationStatus.Operator)]
public async Task Download()
{
var contentDisposition = $"attachment; filename={DateTime.UtcNow:yyyy-MM-dd H:mm:ss} - Node [{ServerStore.NodeTag}] - Logs.zip";
HttpContext.Response.Headers["Content-Disposition"] = contentDisposition;
HttpContext.Response.Headers["Content-Type"] = "application/zip";

var adminLogsFileName = $"admin.logs.download.{Guid.NewGuid():N}";
var adminLogsFilePath = ServerStore._env.Options.DataPager.Options.TempPath.Combine(adminLogsFileName);

var from = GetDateTimeQueryString("from", required: false);
var to = GetDateTimeQueryString("to", required: false);

using (var stream = SafeFileStream.Create(adminLogsFilePath.FullPath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite, 4096,
FileOptions.DeleteOnClose | FileOptions.SequentialScan))
{
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
{
foreach (var filePath in Directory.GetFiles(ServerStore.Configuration.Logs.Path.FullPath))
{
var fileName = Path.GetFileName(filePath);
if (fileName.EndsWith(LoggingSource.LogInfo.LogExtension, StringComparison.OrdinalIgnoreCase) == false &&
fileName.EndsWith(LoggingSource.LogInfo.FullCompressExtension, StringComparison.OrdinalIgnoreCase) == false)
continue;

var hasLogDateTime = LoggingSource.LogInfo.TryGetDate(filePath, out var logDateTime);
if (hasLogDateTime)
{
if (from != null && logDateTime < from)
continue;

if (to != null && logDateTime > to)
continue;
}

try
{
var entry = archive.CreateEntry(fileName);
if (hasLogDateTime)
entry.LastWriteTime = logDateTime;

using (var fs = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
entry.ExternalAttributes = ((int)(FilePermissions.S_IRUSR | FilePermissions.S_IWUSR)) << 16;

await using (var entryStream = entry.Open())
{
await fs.CopyToAsync(entryStream);
}
}
}
catch (Exception e)
{
await DebugInfoPackageUtils.WriteExceptionAsZipEntryAsync(e, archive, fileName);
}
}
}

stream.Position = 0;
await stream.CopyToAsync(ResponseBodyStream());
}
}
}
}
61 changes: 51 additions & 10 deletions src/Raven.Server/Documents/Handlers/Debugging/ThreadsHandler.cs
Expand Up @@ -8,7 +8,9 @@
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Raven.Client.Documents.Conventions;
using Raven.Server.Dashboard;
using Raven.Server.Routing;
using Raven.Server.ServerWide;
using Raven.Server.ServerWide.Context;
using Raven.Server.Utils;
using Raven.Server.Web;
Expand Down Expand Up @@ -46,7 +48,7 @@ await using (var sw = new StringWriter())
await Task.Delay((int)wait);
}

var threadStats = threadsUsage.Calculate(threadIdsAsString.Count == 0 ? null : threadIdsAsString.Select(int.Parse).ToHashSet());
var threadStats = threadsUsage.Calculate(threadIds: threadIdsAsString.Count == 0 ? null : threadIdsAsString.Select(int.Parse).ToHashSet());
result["Threads"] = JArray.FromObject(threadStats.List);

using (ServerStore.ContextPool.AllocateOperationContext(out TransactionOperationContext context))
Expand All @@ -62,23 +64,47 @@ await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBody
[RavenAction("/admin/debug/threads/runaway", "GET", AuthorizationStatus.Operator, IsDebugInformationEndpoint = true)]
public async Task RunawayThreads()
{
var samplesCount = GetIntValueQueryString("samplesCount", required: false) ?? 1;
var interval = GetIntValueQueryString("intervalInMs", required: false) ?? ServerMetricCacher.DefaultCpuRefreshRateInMs;
var maxTopThreads = GetIntValueQueryString("maxTopThreads", required: false);

if (samplesCount <= 0)
throw new ArgumentException("Must be positive", "samplesCount");

if (interval <= 0)
throw new ArgumentException("Must be positive", "interval");

using (ServerStore.ContextPool.AllocateOperationContext(out JsonOperationContext context))
{
await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBodyStream()))
{
try
{
var threadsUsage = new ThreadsUsage();
var threadsInfos = await GetThreadsInfos();

// need to wait to get a correct measure of the cpu
await Task.Delay(100);
if (samplesCount == 1)
{
context.Write(writer,
new DynamicJsonValue
{
["Runaway Threads"] = threadsInfos.First().ToJson()
});
return;
}

var result = threadsUsage.Calculate();
context.Write(writer,
new DynamicJsonValue
{
["Runaway Threads"] = result.ToJson()
});
writer.WriteStartObject();
writer.WritePropertyName("Results");

var dja = new DynamicJsonArray();

foreach (var threadInfo in threadsInfos)
{
dja.Add(threadInfo.ToJson());
}

context.Write(writer, dja);
writer.WriteEndObject();

}
catch (Exception e)
{
Expand All @@ -90,6 +116,21 @@ await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBody
}
}
}

async Task<List<ThreadsInfo>> GetThreadsInfos()
{
var results = new List<ThreadsInfo>();

var threadsUsage = new ThreadsUsage();

for (var i = 0; i < samplesCount; i++)
{
await Task.Delay(interval, ServerStore.ServerShutdown);
results.Add(threadsUsage.Calculate(maxTopThreads));
}

return results;
}
}

[MethodImpl(MethodImplOptions.Synchronized)]
Expand Down
Expand Up @@ -434,7 +434,15 @@ private static BlittableJsonReaderObject GetReduceResult(ulong reduceKeyHash, In
return context.ReadObject(new DynamicJsonValue(), "debug-reduce-result");

if (result.Count > 1)
throw new InvalidOperationException("Cannot have multiple reduce results for a single reduce key");
{
var dvj = new DynamicJsonValue
{
["MergedResults"] = true,
["TotalNumberOfResults"] = result.Count,
["Results"] = new DynamicJsonArray(result.Select(x=>x.Result.Data))
};
return context.ReadObject(dvj, "merged-map-reduce");
}

return result[0].Result.Data;
}
Expand Down
6 changes: 6 additions & 0 deletions src/Raven.Server/Documents/Indexes/Index.cs
Expand Up @@ -18,6 +18,7 @@
using Raven.Client.Documents.Queries;
using Raven.Client.Exceptions.Database;
using Raven.Client.Exceptions.Documents.Indexes;
using Raven.Client.Extensions;
using Raven.Client.ServerWide.Operations;
using Raven.Client.Util;
using Raven.Server.Config;
Expand Down Expand Up @@ -2114,6 +2115,11 @@ private void FlushAndSync(StorageEnvironment storageEnvironment, int timeToWaitI
// index was deleted or database was shutdown
return;
}
catch (AggregateException ae) when (ae.ExtractSingleInnerException() is OperationCanceledException)
{
// index was deleted or database was shutdown
return;
}

storageEnvironment.Cleanup(tryCleanupRecycledJournals);
}
Expand Down
10 changes: 2 additions & 8 deletions src/Raven.Server/NotificationCenter/OutOfMemoryNotifications.cs
Expand Up @@ -6,6 +6,7 @@
using Raven.Server.NotificationCenter.Notifications.Details;
using Sparrow;
using Sparrow.LowMemory;
using Sparrow.Utils;
using Voron;

namespace Raven.Server.NotificationCenter
Expand Down Expand Up @@ -75,14 +76,7 @@ private static MessageDetails OutOfMemoryDetails(Exception exception)

return new MessageDetails
{
Message = $"Managed memory: {new Size(AbstractLowMemoryMonitor.GetManagedMemoryInBytes(), SizeUnit.Bytes)}, " +
$"Unmanaged allocations: {new Size(AbstractLowMemoryMonitor.GetUnmanagedAllocationsInBytes(), SizeUnit.Bytes)}, " +
$"Shared clean: {memoryInfo.SharedCleanMemory}, " +
$"Working set: {memoryInfo.WorkingSet}, " +
$"Available memory: {memoryInfo.AvailableMemory}, " +
$"Calculated Available memory: {memoryInfo.AvailableMemoryForProcessing}, " +
$"Total Scratch Dirty memory: {memoryInfo.TotalScratchDirtyMemory}, " +
$"Total memory: {memoryInfo.TotalPhysicalMemory} {Environment.NewLine}" +
Message = $"{MemoryUtils.GetExtendedMemoryInfo(memoryInfo)} {Environment.NewLine}" +
$"Error: {exception}"
};
}
Expand Down