public void Test_Can_Serialize_Connection_Options() { var options = new FdbConnectionOptions(); Assert.That(options.ToString(), Is.EqualTo("cluster_file=default")); options = new FdbConnectionOptions { ClusterFile = "X:\\some\\path\\to\\fdb.cluster", Root = FdbPath.Parse("/Hello/World"), }; Assert.That(options.ToString(), Is.EqualTo(@"cluster_file=X:\some\path\to\fdb.cluster; root=/Hello/World")); options = new FdbConnectionOptions { ClusterFile = "X:\\some\\path\\to\\fdb.cluster", ReadOnly = true, DefaultTimeout = TimeSpan.FromSeconds(42.5), DefaultRetryLimit = 123, DataCenterId = "AC/DC", MachineId = "Marble Machine X" }; Assert.That(options.ToString(), Is.EqualTo(@"cluster_file=X:\some\path\to\fdb.cluster; readonly; timeout=42.5; retry_limit=123; dc_id=AC/DC; machine_id=""Marble Machine X""")); options = new FdbConnectionOptions { ClusterFile = "/etc/foundationdb/fdb.cluster", MachineId = "James \"The Machine\" Wade", DefaultTimeout = TimeSpan.FromTicks((long)(Math.PI * TimeSpan.TicksPerSecond)), }; Assert.That(options.ToString(), Is.EqualTo(@"cluster_file=/etc/foundationdb/fdb.cluster; timeout=3.1415926; machine_id=""James \""The Machine\"" Wade""")); }
private static Task <IFdbDatabase> ChangeDatabase(FdbConnectionOptions options, CancellationToken ct) { options.DefaultTimeout = TimeSpan.FromSeconds(30); options.DefaultRetryLimit = 50; Program.StdOut("Connecting to cluster...", ConsoleColor.Gray); return(Fdb.OpenAsync(options, ct)); }
public async Task Test_Check_Timeout_On_Non_Existing_Database() { string clusterPath = Path.Combine(TestContext.CurrentContext.WorkDirectory, "notfound.cluster"); File.WriteAllText(clusterPath, "local:[email protected]:4566"); var options = new FdbConnectionOptions { ClusterFile = clusterPath }; using (var db = await Fdb.OpenAsync(options, this.Cancellation)) { bool exists = false; var err = FdbError.Success; try { using (var tr = await db.BeginReadOnlyTransactionAsync(this.Cancellation)) { tr.Timeout = 250; // ms Log("check ..."); await tr.GetAsync(Slice.FromString("key_not_found")); Log("Uhoh ...?"); exists = true; } } catch (FdbException e) { err = e.Code; } Assert.That(exists, Is.False); Assert.That(err, Is.EqualTo(FdbError.TransactionTimedOut)); } }
/// <summary>Connect to the local test partition</summary> public static Task <IFdbDatabase> OpenTestPartitionAsync(CancellationToken ct) { var options = new FdbConnectionOptions { ClusterFile = TestClusterFile, Root = FdbPath.Absolute(FdbPathSegment.Partition("Tests"), FdbPathSegment.Create("Fdb"), FdbPathSegment.Partition(Environment.MachineName)), DefaultTimeout = TimeSpan.FromMilliseconds(DefaultTimeout), }; return(Fdb.OpenAsync(options, ct)); }
//TODO: move these methods to FdbTest ? /// <summary>Connect to the local test database</summary> public static Task <IFdbDatabase> OpenTestDatabaseAsync(CancellationToken ct) { var options = new FdbConnectionOptions { ClusterFile = TestClusterFile, Root = FdbPath.Root, // core tests cannot rely on the DirectoryLayer! DefaultTimeout = TimeSpan.FromMilliseconds(DefaultTimeout), }; return(Fdb.OpenAsync(options, ct)); }
/// <summary>Connect to the local test database</summary> public static Task <IFdbDatabase> OpenTestPartitionAsync(CancellationToken ct) { var options = new FdbConnectionOptions { ClusterFile = TestClusterFile, DbName = TestDbName, PartitionPath = TestPartition, DefaultTimeout = TimeSpan.FromMilliseconds(DefaultTimeout), }; return(Fdb.OpenAsync(options, ct)); }
//TODO: move these methods to FdbTest ? /// <summary>Connect to the local test database</summary> public static Task <IFdbDatabase> OpenTestDatabaseAsync(CancellationToken ct) { var options = new FdbConnectionOptions { ClusterFile = TestClusterFile, DbName = TestDbName, GlobalSpace = KeySubspace.FromKey(TestGlobalPrefix), DefaultTimeout = TimeSpan.FromMilliseconds(DefaultTimeout), }; return(Fdb.OpenAsync(options, ct)); }
public async Task Main() { ThreadPool.SetMinThreads(Environment.ProcessorCount, Environment.ProcessorCount); Fdb.Start(Fdb.GetMaxSafeApiVersion()); var cts = new CancellationTokenSource(); try { var options = new FdbConnectionOptions(); //TODO: change options using the command line arguments? using (var db = await Fdb.OpenAsync(options, cts.Token)) { var location = await db.ReadWriteAsync(async tr => { var subspace = await db.Directory.CreateOrOpenAsync(tr, new[] { "T", "WorkerPool" }); tr.ClearRange(subspace); return(subspace); }, cts.Token); // failsafe: remove this when not debugging problems ! cts.CancelAfter(TimeSpan.FromSeconds(60)); const int N = 100; // msg/publiser const int K = 2; // publishers const int W = 2; // workers await RunAsync(db, location, cts.Token, () => cts.Cancel(), N, K, W); } } catch (TaskCanceledException) { Console.WriteLine("CANCELED"); } catch (Exception e) { cts.Cancel(); Console.Error.WriteLine("CRASH: " + e.ToString()); Console.Error.WriteLine(); } finally { Fdb.Stop(); } }
private static async Task MainAsync(string[] args, CancellationToken cancel) { #region Options Parsing... string clusterFile = null; var partition = FdbPath.Root; bool showHelp = false; int timeout = 30; int maxRetries = 10; string execCommand = null; var opts = new OptionSet() { { "c|C|connfile=", "The path of a file containing the connection string for the FoundationDB cluster.", v => clusterFile = v }, { "p|partition=", "The name of the database partition to open.", v => partition = FdbPath.Parse(v.Trim()) }, { "t|timeout=", "Default timeout (in seconds) for failed transactions.", (int v) => timeout = v }, { "r|retries=", "Default max retry count for failed transactions.", (int v) => maxRetries = v }, { "exec=", "Execute this command, and exits immediately.", v => execCommand = v }, { "h|help", "Show this help and exit.", v => showHelp = v != null } }; var extra = opts.Parse(args); if (showHelp) { //TODO! opts.WriteOptionDescriptions(Console.Out); return; } string startCommand = null; if (!string.IsNullOrEmpty(execCommand)) { startCommand = execCommand; } else if (extra.Count > 0) { // the remainder of the command line will be the first command to execute startCommand = String.Join(" ", extra); } #endregion bool stop = false; Db = null; try { var cnxOptions = new FdbConnectionOptions { ClusterFile = clusterFile, Root = partition }; Db = await ChangeDatabase(cnxOptions, cancel); Db.DefaultTimeout = Math.Max(0, timeout) * 1000; Db.DefaultRetryLimit = Math.Max(0, maxRetries); StdOut("Using API v" + Fdb.ApiVersion + " (max " + Fdb.GetMaxApiVersion() + ")", ConsoleColor.Gray); StdOut("Cluster file: " + (clusterFile ?? "<default>"), ConsoleColor.Gray); StdOut(""); StdOut("FoundationDB Shell menu:"); StdOut("\tcd\tChange the current directory"); StdOut("\tdir\tList the sub-directories the current directory"); StdOut("\tshow\tShow the content of the current directory"); StdOut("\ttree\tShow all the directories under the current directory"); StdOut("\tsampling\tDisplay statistics on random shards from the database"); StdOut("\tcoordinators\tShow the current coordinators for the cluster"); //StdOut("\thelp\tShow all the commands"); StdOut("\tquit\tQuit"); StdOut(""); try { var cf = await Fdb.System.GetCoordinatorsAsync(Db, cancel); Description = cf.Description; StdOut("Ready...", ConsoleColor.DarkGreen); } catch (Exception e) { StdErr("Failed to get coordinators state from cluster: " + e.Message, ConsoleColor.DarkRed); Description = "???"; } StdOut(""); var le = new LineEditor("FDBShell"); string[] cmds = new string[] { "cd", "clear", "coordinators", "count", "dir", "dump", "exit", "gc", "help", "layer", "map", "mem", "mkdir", "mv", "partition", "pwd", "quit", "ren", "rmdir", "sampling", "shards", "show", "status", "topology", "tree", "version", "wide", }; le.AutoCompleteEvent = (txt, pos) => { string[] res; int p = txt.IndexOf(' '); if (p > 0) { string cmd = txt.Substring(0, p); string arg = txt.Substring(p + 1).Trim(); if (cmd == "cd" || cmd == "rmdir") { // handle completion for directories // txt: "cd foo" => prefix = "foo" // txt: "cd foobar/b" => prefix = "b" bool hasLeadingSlash = arg.EndsWith("/"); var path = FdbPath.Parse(hasLeadingSlash ? (arg + "!") : arg); var parent = path.Count > 1 ? path.GetParent() : path.IsAbsolute ? FdbPath.Root : FdbPath.Empty; string search = hasLeadingSlash ? "" : path.Name; var subdirs = RunAsyncCommand((db, log, ct) => AutoCompleteDirectories(CombinePath(CurrentDirectoryPath, parent.ToString()), db, log, ct), cancel).GetAwaiter().GetResult(); if (!subdirs.HasValue || subdirs.Value == null) { return(new LineEditor.Completion(txt, null)); } res = subdirs.Value .Where(s => s.StartsWith(search, StringComparison.Ordinal)) .Select(s => (cmd + " " + parent[s]).Substring(txt.Length)) .ToArray(); if (res.Length == 1 && res[0] == string.Empty) { // someone was at "cd /Foo/Bar", pressed TAB again, and there is no other match // => we interpret it as "want to go in the sub-folder res = new[] { "/" }; // add a "slash" } return(new LineEditor.Completion(txt, res)); } // unknown command return(new LineEditor.Completion(txt, null)); } // list of commands res = cmds .Where(cmd => cmd.StartsWith(txt, StringComparison.OrdinalIgnoreCase)) .Select(cmd => cmd.Substring(txt.Length)) .ToArray(); return(new LineEditor.Completion(txt, res)); }; le.TabAtStartCompletes = true; string prompt = null; void UpdatePrompt(FdbPath path) { prompt = $"[fdb:{Description} {path.ToString()}]# "; } le.PromptColor = ConsoleColor.Cyan; UpdatePrompt(CurrentDirectoryPath); while (!stop) { string s; if (startCommand != null) { s = startCommand; startCommand = null; } else { s = startCommand ?? le.Edit(prompt, ""); } if (s == null) { break; } //TODO: we need a tokenizer that recognizes binary keys, tuples, escaped paths, etc... var tokens = Tokenize(s); string cmd = tokens.Count > 0 ? tokens.Get <string>(0) : string.Empty; var extras = tokens.Count > 1 ? tokens.Substring(1) : STuple.Empty; var trimmedCommand = cmd.Trim().ToLowerInvariant(); try { switch (trimmedCommand) { case "": { continue; } case "log": { string prm = PopParam(ref extras); LogCommand(prm, extras, Console.Out); break; } case "version": { await VersionCommand(extras, clusterFile, Console.Out, cancel); break; } case "tree": { string prm = PopParam(ref extras); var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.Tree(path, extras, db, log, ct), cancel); break; } case "map": { string prm = PopParam(ref extras); var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.Map(path, extras, db, log, ct), cancel); break; } case "dir": case "ls": { string prm = PopParam(ref extras); var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.Dir(path, extras, BasicCommands.DirectoryBrowseOptions.Default, db, log, ct), cancel); break; } case "ll": { string prm = PopParam(ref extras); var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.Dir(path, extras, BasicCommands.DirectoryBrowseOptions.ShowCount, db, log, ct), cancel); break; } case "count": { string prm = PopParam(ref extras); var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.Count(path, extras, db, log, ct), cancel); break; } case "show": case "top": { await RunAsyncCommand((db, log, ct) => BasicCommands.Show(CurrentDirectoryPath, extras, false, db, log, ct), cancel); break; } case "last": { await RunAsyncCommand((db, log, ct) => BasicCommands.Show(CurrentDirectoryPath, extras, true, db, log, ct), cancel); break; } case "dump": { string output = PopParam(ref extras); if (string.IsNullOrEmpty(output)) { StdErr("You must specify a target file path.", ConsoleColor.Red); break; } await RunAsyncCommand((db, log, ct) => BasicCommands.Dump(CurrentDirectoryPath, output, extras, db, log, ct), cancel); break; } case "cd": case "pwd": { string prm = PopParam(ref extras); if (!string.IsNullOrEmpty(prm)) { var newPath = CombinePath(CurrentDirectoryPath, prm); var res = await RunAsyncCommand( (db, log, ct) => db.ReadAsync(tr => BasicCommands.TryOpenCurrentDirectoryAsync(tr, newPath), ct), cancel ); if (res.Failed) { StdErr($"# Failed to open Directory {newPath}: {res.Error.Message}", ConsoleColor.Red); Console.Beep(); } else if (res.Value == null) { StdOut($"# Directory {newPath} does not exist!", ConsoleColor.Red); Console.Beep(); } else { CurrentDirectoryPath = newPath; UpdatePrompt(CurrentDirectoryPath); } } else { var res = await RunAsyncCommand( (db, log, ct) => db.ReadAsync(tr => BasicCommands.TryOpenCurrentDirectoryAsync(tr, CurrentDirectoryPath), ct), cancel ); if (res.Failed) { StdErr($"# Failed to query Directory {Program.CurrentDirectoryPath}: {res.Error.Message}", ConsoleColor.Red); } else if (res.Value == null) { StdOut($"# Directory {Program.CurrentDirectoryPath} does not exist anymore"); } } break; } case "mkdir": case "md": { // "mkdir DIRECTORYNAME" string prm = PopParam(ref extras); if (!string.IsNullOrEmpty(prm)) { var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.CreateDirectory(path, extras, db, log, ct), cancel); } break; } case "rmdir": { // "rmdir DIRECTORYNAME" string prm = PopParam(ref extras); if (!string.IsNullOrEmpty(prm)) { var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.RemoveDirectory(path, extras, db, log, ct), cancel); } break; } case "mv": case "ren": { // "mv SOURCE DESTINATION" string prm = PopParam(ref extras); var srcPath = CombinePath(CurrentDirectoryPath, prm); var dstPath = CombinePath(CurrentDirectoryPath, extras.Get <string>(0)); await RunAsyncCommand((db, log, ct) => BasicCommands.MoveDirectory(srcPath, dstPath, extras.Substring(1), db, log, ct), cancel); break; } case "get": { // "get KEY" if (extras.Count == 0) { StdErr("You must specify a key to read.", ConsoleColor.Red); break; } await RunAsyncCommand((db, log, ct) => BasicCommands.Get(CurrentDirectoryPath, extras, db, log, ct), cancel); break; } case "clear": { // "clear KEY" if (extras.Count == 0) { StdErr("You must specify a key to clear.", ConsoleColor.Red); break; } await RunAsyncCommand((db, log, ct) => BasicCommands.Clear(CurrentDirectoryPath, extras, db, log, ct), cancel); break; } case "clearrange": { // "clear *" or "clear FROM TO" if (extras.Count == 0) { StdErr("You must specify either '*', a prefix, or a key range.", ConsoleColor.Red); break; } await RunAsyncCommand((db, log, ct) => BasicCommands.ClearRange(CurrentDirectoryPath, extras, db, log, ct), cancel); break; } case "layer": { string prm = PopParam(ref extras); if (string.IsNullOrEmpty(prm)) { // displays the layer id of the current folder await RunAsyncCommand((db, log, ct) => BasicCommands.ShowDirectoryLayer(CurrentDirectoryPath, extras, db, log, ct), cancel); } else { // change the layer id of the current folder prm = prm.Trim(); // double or single quotes can be used to escape the value if (prm.Length >= 2 && (prm.StartsWith("'") && prm.EndsWith("'")) || (prm.StartsWith("\"") && prm.EndsWith("\""))) { prm = prm.Substring(1, prm.Length - 2); } await RunAsyncCommand((db, log, ct) => BasicCommands.ChangeDirectoryLayer(CurrentDirectoryPath, prm, extras, db, log, ct), cancel); } break; } case "mkpart": { // "mkpart PARTITIONNAME" string prm = PopParam(ref extras); if (!string.IsNullOrEmpty(prm)) { var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.CreateDirectory(path, STuple.Create(FdbDirectoryPartition.LayerId).Concat(extras), db, log, ct), cancel); } break; } case "topology": { await RunAsyncCommand((db, log, ct) => BasicCommands.Topology(null, extras, db, log, ct), cancel); break; } case "shards": { string prm = PopParam(ref extras); var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.Shards(path, extras, db, log, ct), cancel); break; } case "sampling": { string prm = PopParam(ref extras); var path = CombinePath(CurrentDirectoryPath, prm); await RunAsyncCommand((db, log, ct) => BasicCommands.Sampling(path, extras, db, log, ct), cancel); break; } case "coordinators": { await RunAsyncCommand((db, log, ct) => CoordinatorsCommand(db, log, ct), cancel); break; } case "partition": { string prm = PopParam(ref extras); if (string.IsNullOrEmpty(prm)) { StdOut($"# Current partition is {partition}"); //TODO: browse existing partitions ? break; } var newPartition = FdbPath.Parse(prm.Trim()); IFdbDatabase newDb = null; try { var options = new FdbConnectionOptions { ClusterFile = clusterFile, Root = newPartition }; newDb = await ChangeDatabase(options, cancel); } catch (Exception) { newDb?.Dispose(); newDb = null; throw; } finally { if (newDb != null) { if (Db != null) { Db.Dispose(); Db = null; } Db = newDb; partition = newPartition; StdOut($"# Changed partition to {partition}"); } } break; } case "q": case "x": case "quit": case "exit": case "bye": { stop = true; break; } case "gc": { long before = GC.GetTotalMemory(false); Console.Write("Collecting garbage..."); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); StdOut(" Done"); long after = GC.GetTotalMemory(false); StdOut("- before = " + before.ToString("N0")); StdOut("- after = " + after.ToString("N0")); StdOut("- delta = " + (before - after).ToString("N0")); break; } case "mem": { StdOut("Memory usage:"); StdOut("- Managed Mem : " + GC.GetTotalMemory(false).ToString("N0")); //TODO: how do we get these values on Linux/Mac? #if !NETCOREAPP StdOut("- Working Set : " + PerfCounters.WorkingSet.NextValue().ToString("N0") + " (peak " + PerfCounters.WorkingSetPeak.NextValue().ToString("N0") + ")"); StdOut("- Virtual Bytes: " + PerfCounters.VirtualBytes.NextValue().ToString("N0") + " (peak " + PerfCounters.VirtualBytesPeak.NextValue().ToString("N0") + ")"); StdOut("- Private Bytes: " + PerfCounters.PrivateBytes.NextValue().ToString("N0")); StdOut("- BytesInAlHeap: " + PerfCounters.ClrBytesInAllHeaps.NextValue().ToString("N0")); #endif break; } case "wide": { try { Console.WindowWidth = 160; } catch (Exception e) { StdErr("Failed to change console width: " + e.Message, ConsoleColor.DarkRed); } break; } case "status": case "wtf": { var result = await RunAsyncCommand((_, log, ct) => FdbCliCommands.RunFdbCliCommand("status details", null, clusterFile, log, ct), cancel); if (result.Failed) { break; } if (result.Value.ExitCode != 0) { StdErr($"# fdbcli exited with code {result.Value.ExitCode}", ConsoleColor.DarkRed); StdOut("> StdErr:", ConsoleColor.DarkGray); StdOut(result.Value.StdErr); StdOut("> StdOut:", ConsoleColor.DarkGray); } StdOut(result.Value.StdOut); break; } default: { StdErr($"Unknown command : '{trimmedCommand}'", ConsoleColor.Red); break; } } } catch (Exception e) { StdErr($"Failed to execute command '{trimmedCommand}': " + e.Message, ConsoleColor.Red); #if DEBUG StdErr(e.ToString(), ConsoleColor.DarkRed); #endif } if (!string.IsNullOrEmpty(execCommand)) { // only run one command, and then exit break; } } } finally { Program.Db?.Dispose(); } }
private static Task <IFdbDatabase> ChangeDatabase(FdbConnectionOptions options, CancellationToken ct) { options.DefaultTimeout = TimeSpan.FromSeconds(30); options.DefaultRetryLimit = 50; return(Fdb.OpenAsync(options, ct)); }
private static async Task MainAsync(string[] args, CancellationToken cancel) { #region Options Parsing... string clusterFile = null; var dbName = "DB"; var partition = new string[0]; bool showHelp = false; int timeout = 30; int maxRetries = 10; string execCommand = null; var opts = new OptionSet() { { "c|connfile=", "The path of a file containing the connection string for the FoundationDB cluster.", v => clusterFile = v }, { "p|partition=", "The name of the database partition to open.", v => partition = v.Trim().Split('/') }, { "t|timeout=", "Default timeout (in seconds) for failed transactions.", (int v) => timeout = v }, { "r|retries=", "Default max retry count for failed transactions.", (int v) => maxRetries = v }, { "exec=", "Execute this command, and exits immediately.", v => execCommand = v }, { "h|help", "Show this help and exit.", v => showHelp = v != null } }; var extra = opts.Parse(args); if (showHelp) { //TODO! opts.WriteOptionDescriptions(Console.Out); return; } string startCommand = null; if (!string.IsNullOrEmpty(execCommand)) { startCommand = execCommand; } else if (extra.Count > 0) { // the remainder of the command line will be the first command to execute startCommand = String.Join(" ", extra); } #endregion bool stop = false; Db = null; try { var cnxOptions = new FdbConnectionOptions { ClusterFile = clusterFile, DbName = dbName, PartitionPath = partition }; Db = await ChangeDatabase(cnxOptions, cancel); Db.DefaultTimeout = Math.Max(0, timeout) * 1000; Db.DefaultRetryLimit = Math.Max(0, maxRetries); Console.WriteLine("Using API v" + Fdb.ApiVersion + " (max " + Fdb.GetMaxApiVersion() + ")"); Console.WriteLine("Cluster file: " + (clusterFile ?? "<default>")); Console.WriteLine(); Console.WriteLine("FoundationDB Shell menu:"); Console.WriteLine("\tdir\tShow the content of the current directory"); Console.WriteLine("\ttree\tShow all the directories under the current directory"); Console.WriteLine("\tsampling\tDisplay statistics on random shards from the database"); Console.WriteLine("\tcoordinators\tShow the current coordinators for the cluster"); Console.WriteLine("\tmem\tShow memory usage statistics"); Console.WriteLine("\tgc\tTrigger garbage collection"); Console.WriteLine("\tquit\tQuit"); Console.WriteLine("Ready..."); var le = new LineEditor("FDBShell"); string[] cmds = new string[] { "cd", "coordinators", "count", "dir", "exit", "gc", "help", "layer", "map", "mem", "mkdir", "mv", "partition", "pwd", "quit", "ren", "rmdir", "sampling", "shards", "show", "status", "topology", "tree", "version", "wide", }; le.AutoCompleteEvent = (txt, pos) => { string[] res; int p = txt.IndexOf(' '); if (p > 0) { string cmd = txt.Substring(0, p); string arg = txt.Substring(p + 1); if (cmd == "cd") { // handle completion for directories // txt: "cd foo" => prefix = "foo" // txt: "cd foobar/b" => prefix = "b" string path = CurrentDirectoryPath; string prefix = ""; string search = arg; p = arg.LastIndexOf('/'); if (p > 0) { path = Path.Combine(path, arg.Substring(0, p)); search = arg.Substring(p + 1); prefix = arg.Substring(0, p + 1); } var subdirs = RunAsyncCommand((db, log, ct) => AutoCompleteDirectories(path, db, log, ct), cancel).GetAwaiter().GetResult(); if (!subdirs.HasValue || subdirs.Value == null) { return(new LineEditor.Completion(txt, null)); } res = subdirs.Value .Where(s => s.StartsWith(search, StringComparison.Ordinal)) .Select(s => (cmd + " " + prefix + s).Substring(txt.Length)) .ToArray(); return(new LineEditor.Completion(txt, res)); } // unknown command return(new LineEditor.Completion(txt, null)); } // list of commands res = cmds .Where(cmd => cmd.StartsWith(txt, StringComparison.OrdinalIgnoreCase)) .Select(cmd => cmd.Substring(txt.Length)) .ToArray(); return(new LineEditor.Completion(txt, res)); }; le.TabAtStartCompletes = true; string prompt = null; Action <string> updatePrompt = (path) => { prompt = String.Format("fdb:{0}> ", path); }; updatePrompt(CurrentDirectoryPath); while (!stop) { string s = startCommand != null ? startCommand : le.Edit(prompt, ""); startCommand = null; if (s == null) { break; } var tokens = s.Trim().Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string cmd = tokens.Length > 0 ? tokens[0] : String.Empty; string prm = tokens.Length > 1 ? tokens[1] : String.Empty; var extras = tokens.Length > 2 ? STuple.FromEnumerable <string>(tokens.Skip(2)) : STuple.Empty; var trimmedCommand = cmd.Trim().ToLowerInvariant(); switch (trimmedCommand) { case "": { continue; } case "log": { LogCommand(prm, Console.Out); break; } case "version": { await VersionCommand(prm, clusterFile, Console.Out, cancel); break; } case "tree": { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.Tree(path, extras, db, log, ct), cancel); break; } case "map": { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.Map(path, extras, db, log, ct), cancel); break; } case "dir": case "ls": { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.Dir(path, extras, BasicCommands.DirectoryBrowseOptions.Default, db, log, ct), cancel); break; } case "ll": { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.Dir(path, extras, BasicCommands.DirectoryBrowseOptions.ShowCount, db, log, ct), cancel); break; } case "count": { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.Count(path, extras, db, log, ct), cancel); break; } case "show": case "top": { var path = ParsePath(CurrentDirectoryPath); await RunAsyncCommand((db, log, ct) => BasicCommands.Show(path, extras, false, db, log, ct), cancel); break; } case "last": { var path = ParsePath(CurrentDirectoryPath); await RunAsyncCommand((db, log, ct) => BasicCommands.Show(path, extras, true, db, log, ct), cancel); break; } case "cd": case "pwd": { if (!string.IsNullOrEmpty(prm)) { var newPath = CombinePath(CurrentDirectoryPath, prm); var res = await RunAsyncCommand((db, log, ct) => BasicCommands.TryOpenCurrentDirectoryAsync(ParsePath(newPath), db, ct), cancel); if (res.Failed) { Console.Error.WriteLine("# Failed to open Directory {0}: {1}", newPath, res.Error.Message); Console.Beep(); } else if (res.Value == null) { Console.WriteLine("# Directory {0} does not exist!", newPath); Console.Beep(); } else { CurrentDirectoryPath = newPath; updatePrompt(CurrentDirectoryPath); } } else { var res = await RunAsyncCommand((db, log, ct) => BasicCommands.TryOpenCurrentDirectoryAsync(ParsePath(CurrentDirectoryPath), db, ct), cancel); if (res.Failed) { Console.Error.WriteLine("# Failed to query Directory {0}: {1}", Program.CurrentDirectoryPath, res.Error.Message); } else if (res.Value == null) { Console.WriteLine("# Directory {0} does not exist anymore", CurrentDirectoryPath); } else { Console.WriteLine("# {0}", res); } } break; } case "mkdir": case "md": { // "mkdir DIRECTORYNAME" if (!string.IsNullOrEmpty(prm)) { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.CreateDirectory(path, extras, db, log, ct), cancel); } break; } case "rmdir": { // "rmdir DIRECTORYNAME" if (!string.IsNullOrEmpty(prm)) { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.RemoveDirectory(path, extras, db, log, ct), cancel); } break; } case "mv": case "ren": { // "mv SOURCE DESTINATION" var srcPath = ParsePath(CombinePath(CurrentDirectoryPath, prm)); var dstPath = ParsePath(CombinePath(CurrentDirectoryPath, extras.Get <string>(0))); await RunAsyncCommand((db, log, ct) => BasicCommands.MoveDirectory(srcPath, dstPath, extras.Substring(1), db, log, ct), cancel); break; } case "layer": { if (string.IsNullOrEmpty(prm)) { // displays the layer id of the current folder var path = ParsePath(CurrentDirectoryPath); await RunAsyncCommand((db, log, ct) => BasicCommands.ShowDirectoryLayer(path, extras, db, log, ct), cancel); } else { // change the layer id of the current folder prm = prm.Trim(); // double or single quotes can be used to escape the value if (prm.Length >= 2 && (prm.StartsWith("'") && prm.EndsWith("'")) || (prm.StartsWith("\"") && prm.EndsWith("\""))) { prm = prm.Substring(1, prm.Length - 2); } var path = ParsePath(CurrentDirectoryPath); await RunAsyncCommand((db, log, ct) => BasicCommands.ChangeDirectoryLayer(path, prm, extras, db, log, ct), cancel); } break; } case "mkpart": { // "mkpart PARTITIONNAME" if (!string.IsNullOrEmpty(prm)) { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.CreateDirectory(path, STuple.Create(FdbDirectoryPartition.LayerId).Concat(extras), db, log, ct), cancel); } break; } case "topology": { await RunAsyncCommand((db, log, ct) => BasicCommands.Topology(null, extras, db, log, ct), cancel); break; } case "shards": { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.Shards(path, extras, db, log, ct), cancel); break; } case "sampling": { var path = ParsePath(CombinePath(CurrentDirectoryPath, prm)); await RunAsyncCommand((db, log, ct) => BasicCommands.Sampling(path, extras, db, log, ct), cancel); break; } case "coordinators": { await RunAsyncCommand((db, log, ct) => CoordinatorsCommand(db, log, ct), cancel); break; } case "partition": { if (string.IsNullOrEmpty(prm)) { Console.WriteLine("# Current partition is {0}", String.Join("/", partition)); //TODO: browse existing partitions ? break; } var newPartition = prm.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); IFdbDatabase newDb = null; try { var options = new FdbConnectionOptions { ClusterFile = clusterFile, DbName = dbName, PartitionPath = newPartition }; newDb = await ChangeDatabase(options, cancel); } catch (Exception) { if (newDb != null) { newDb.Dispose(); } newDb = null; throw; } finally { if (newDb != null) { if (Db != null) { Db.Dispose(); Db = null; } Db = newDb; partition = newPartition; Console.WriteLine("# Changed partition to {0}", partition); } } break; } case "q": case "x": case "quit": case "exit": case "bye": { stop = true; break; } case "gc": { long before = GC.GetTotalMemory(false); Console.Write("Collecting garbage..."); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Console.WriteLine(" Done"); long after = GC.GetTotalMemory(false); Console.WriteLine("- before = " + before.ToString("N0")); Console.WriteLine("- after = " + after.ToString("N0")); Console.WriteLine("- delta = " + (before - after).ToString("N0")); break; } case "mem": { Console.WriteLine("Memory usage:"); Console.WriteLine("- Managed Mem : " + GC.GetTotalMemory(false).ToString("N0")); //TODO: how do we get these values on Linux/Mac? #if !NETCOREAPP Console.WriteLine("- Working Set : " + PerfCounters.WorkingSet.NextValue().ToString("N0") + " (peak " + PerfCounters.WorkingSetPeak.NextValue().ToString("N0") + ")"); Console.WriteLine("- Virtual Bytes: " + PerfCounters.VirtualBytes.NextValue().ToString("N0") + " (peak " + PerfCounters.VirtualBytesPeak.NextValue().ToString("N0") + ")"); Console.WriteLine("- Private Bytes: " + PerfCounters.PrivateBytes.NextValue().ToString("N0")); Console.WriteLine("- BytesInAlHeap: " + PerfCounters.ClrBytesInAllHeaps.NextValue().ToString("N0")); #endif break; } case "wide": { Console.WindowWidth = 160; break; } case "status": case "wtf": { var result = await RunAsyncCommand((_, log, ct) => FdbCliCommands.RunFdbCliCommand("status details", null, clusterFile, log, ct), cancel); if (result.Failed) { break; } if (result.Value.ExitCode != 0) { Console.WriteLine("# fdbcli exited with code {0}", result.Value.ExitCode); Console.WriteLine("> StdErr:"); Console.WriteLine(result.Value.StdErr); Console.WriteLine("> StdOut:"); } Console.WriteLine(result.Value.StdOut); break; } default: { Console.WriteLine(string.Format("Unknown command : '{0}'", trimmedCommand)); break; } } if (!string.IsNullOrEmpty(execCommand)) { // only run one command, and then exit break; } } } finally { if (Db != null) { Db.Dispose(); } } }
private static async Task MainAsync(string[] args, CancellationToken cancel) { Console.CursorVisible = false; Console.TreatControlCAsInput = true; try { CancellationTokenSource cts = null; Task burner = null; const int CAPACITY = 4 * 2; var history = new Queue <Datum>(CAPACITY); var options = new FdbConnectionOptions { ClusterFile = Program.ClusterPath, DefaultTimeout = TimeSpan.FromSeconds(10) }; //TODO: proper parsing of command line arguments! using (var db = await Fdb.OpenAsync(options, cancel)) { bool exit = false; bool hot = false; bool repaint = true; var processName = Process.GetCurrentProcess().ProcessName; var perCpu = new PerformanceCounter("Process", "% Processor Time", processName); var perfDiskReads = new PerformanceCounter("PhysicalDisk", "Disk Read Bytes/sec", "0 C:"); var perfDiskWrites = new PerformanceCounter("PhysicalDisk", "Disk Write Bytes/sec", "0 C:"); var perfDiskWriteIops = new PerformanceCounter("PhysicalDisk", "Disk Writes/sec", "0 C:"); var perfDiskReadIops = new PerformanceCounter("PhysicalDisk", "Disk Reads/sec", "0 C:"); const int COL0 = 1; const int COL1 = COL0 + 15; const int COL2 = COL1 + 15; const int COL3 = COL2 + 15; const int COL4 = COL3 + 15; while (!exit && !cancel.IsCancellationRequested) { if (Console.KeyAvailable) { var k = Console.ReadKey(); switch (k.Key) { case ConsoleKey.Escape: { // [ESC] exit = true; break; } case ConsoleKey.C: { if (k.Modifiers.HasFlag(ConsoleModifiers.Control)) { // CTRL-C exit = true; } break; } case ConsoleKey.R: { Randomized = !Randomized; repaint = true; break; } case ConsoleKey.V: { // Change Value Size CurrentSize = (CurrentSize + 1) % VALUE_SIZES.Length; Value = Slice.Random(Rnd, VALUE_SIZES[CurrentSize]); repaint = true; break; } case ConsoleKey.Spacebar: { hot = !hot; repaint = true; if (hot) { cts = new CancellationTokenSource(); burner = Task.Run(() => BurnerThread(db, cts.Token), cts.Token); } else { cts.Cancel(); try { await burner; } catch (TaskCanceledException) { } cts.Dispose(); } break; } } } if (!repaint) { await Task.Delay(250); } long curKeys = Volatile.Read(ref Keys); long curTrans = Volatile.Read(ref Transactions); long curBytes = Volatile.Read(ref Bytes); double curDiskWrites = perfDiskWrites.NextValue(); double curDiskReads = perfDiskReads.NextValue(); double curDiskWriteIo = perfDiskWriteIops.NextValue(); double curDiskReadIo = perfDiskReadIops.NextValue(); while (history.Count >= CAPACITY) { history.Dequeue(); } var now = DateTime.UtcNow; history.Enqueue(new Datum { Date = now, Keys = curKeys, Commits = curTrans, Bytes = curBytes, DiskWriteBps = curDiskWrites, DiskReadBps = curDiskReads, DiskWriteIops = curDiskWriteIo, DiskReadIops = curDiskReadIo, }); if (repaint) { Console.Title = "FdbBurner - " + (!hot ? "ICY COLD" : Randomized ? "HOT HOT HOT" : "HOT HOT"); Console.BackgroundColor = !hot ? ConsoleColor.DarkCyan : Randomized ? ConsoleColor.DarkRed : ConsoleColor.DarkGreen; Console.Clear(); Console.ForegroundColor = ConsoleColor.Gray; WriteAt(COL0, 1, "Pattern : {0,10}", ""); WriteAt(COL2, 1, "Value Size: {0,6} bytes", ""); WriteAt(COL0, 3, "{0,-12}", "Transactions"); WriteAt(COL1, 3, "{0,-12}", "Keys"); WriteAt(COL2, 3, "{0,-10}", "Written Bytes"); WriteAt(COL3, 3, "{0,-10}", "Disk Writes"); WriteAt(COL4, 3, "{0,-10}", "Disk Reads"); WriteAt(COL3, 7, "{0,-10}", "Write IOPS"); WriteAt(COL4, 7, "{0,-10}", "Read IOPS"); repaint = false; } Console.ForegroundColor = ConsoleColor.White; WriteAt(COL0 + 12, 1, "{0,-10}", Randomized ? "Random" : "Sequential"); WriteAt(COL2 + 12, 1, "{0,6:N0}", Value.Count); WriteAt(COL0, 4, "{0,12:N0}", curTrans); WriteAt(COL1, 4, "{0,12:N0}", curKeys); WriteAt(COL2, 4, "{0,10:N1} MB", curBytes / 1048576.0); WriteAt(COL3, 4, "{0,10:N1} MB/s", curDiskWrites / 1048576.0); WriteAt(COL4, 4, "{0,10:N1} MB/s", curDiskReads / 1048576.0); if (history.Count > 1) { var old = history.Peek(); var dur = (now - old.Date).TotalSeconds; double speed; Console.ForegroundColor = ConsoleColor.White; speed = (curTrans - old.Commits) / dur; WriteAt(COL0, 5, "{0,12:N0}", speed); speed = (curKeys - old.Keys) / dur; WriteAt(COL1, 5, "{0,12:N0}", speed); speed = (curBytes - old.Bytes) / dur; WriteAt(COL2, 5, "{0,10:N1} MB/s", speed / 1048576.0); var writeSpeed = history.Average(d => d.DiskWriteBps); var readSpeed = history.Average(d => d.DiskReadBps); WriteAt(COL3, 5, "{0,10:N1} MB/s", writeSpeed / 1048576.0); WriteAt(COL4, 5, "{0,10:N1} MB/s", readSpeed / 1048576.0); var writeIops = history.Average(d => d.DiskWriteIops); var readIops = history.Average(d => d.DiskReadIops); WriteAt(COL3, 8, "{0,10:N0} iops", writeIops); WriteAt(COL4, 8, "{0,10:N0} iops", readIops); var factor = speed > 0 ? writeSpeed / speed : 0; WriteLarge(0, 16, "{0,8:F3}", speed / 1048576.0); WriteLarge(0, 24, "{0,8:F3}", writeSpeed / 1048576.0); WriteLarge(0, 32, "X{0,5:F1}", factor); } Console.SetCursorPosition(0, 0); } } } finally { Console.CursorVisible = true; Console.ResetColor(); Console.Clear(); } }
public static IFdbDatabaseProviderBuilder WithConnectionString([NotNull] this IFdbDatabaseProviderBuilder builder, [NotNull] FdbConnectionOptions options) { Contract.NotNull(options, nameof(options)); builder.Services.Configure <FdbDatabaseProviderOptions>(c => { c.ConnectionOptions = options; }); return(builder); }
static void Main(string[] args) { bool stop = false; string clusterFile = null; var partition = FdbPath.Root; int pStart = 0; string startCommand = null; while (pStart < args.Length) { if (args[pStart].StartsWith("-")) { switch (args[pStart].Substring(1)) { case "C": case "c": { clusterFile = args[pStart + 1]; pStart += 2; break; } case "P": case "p": { partition = FdbPath.Parse(args[pStart + 1].Trim()); pStart += 2; break; } default: { Console.WriteLine($"Unknown option : '{args[pStart]}'"); pStart++; break; } } } else { break; } } if (args.Length > 0 && pStart < args.Length) { // the remainder of the command line will be the first command to execute startCommand = String.Join(" ", args, pStart, args.Length - pStart); } var go = new CancellationTokenSource(); // Initialize FDB Fdb.Start(Fdb.GetDefaultApiVersion()); try { var options = new FdbConnectionOptions { ClusterFile = clusterFile, Root = partition, }; Db = Fdb.OpenAsync(options, go.Token).GetAwaiter().GetResult(); using (Db) { Db.DefaultTimeout = 30 * 1000; Db.DefaultRetryLimit = 10; Console.WriteLine("Using API v" + Fdb.ApiVersion + " (max " + Fdb.GetMaxApiVersion() + ")"); Console.WriteLine("Cluster file: " + (clusterFile ?? "<default>")); Console.WriteLine(); Console.WriteLine("FoundationDB Samples menu:"); Console.WriteLine("\t1\tRun Class Scheduling sample"); Console.WriteLine("\tL\tRun Leak test"); Console.WriteLine("\tbench\tRun synthetic benchmarks"); Console.WriteLine("\tgc\tTrigger a .NET garbage collection"); Console.WriteLine("\tmem\tDisplay memory usage statistics"); Console.WriteLine("\tq\tQuit"); Console.WriteLine("Ready..."); while (!stop) { Console.Write("> "); string s = startCommand != null ? startCommand : Console.ReadLine(); startCommand = null; var tokens = s.Trim().Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); string cmd = tokens.Length > 0 ? tokens[0] : String.Empty; string prm = tokens.Length > 1 ? tokens[1] : String.Empty; var trimmedCommand = cmd.Trim().ToLowerInvariant(); switch (trimmedCommand) { case "": { continue; } case "1": { // Class Scheduling RunAsyncTest(new ClassScheduling(), go.Token); break; } case "log": { switch (prm.ToLowerInvariant()) { case "on": { LogEnabled = true; Console.WriteLine("# Logging enabled"); break; } case "off": { LogEnabled = false; Console.WriteLine("# Logging disabled"); break; } default: { Console.WriteLine("# Logging is {0}", LogEnabled ? "ON" : "OFF"); break; } } break; } case "bench": { // Benchs switch (prm.ToLowerInvariant()) { case "read": { RunAsyncTest(new BenchRunner(BenchRunner.BenchMode.GetReadVersion), go.Token); break; } case "get": { RunAsyncTest(new BenchRunner(BenchRunner.BenchMode.Get), go.Token); break; } case "get10": { RunAsyncTest(new BenchRunner(BenchRunner.BenchMode.Get, 10), go.Token); break; } case "set": { // Bench Set RunAsyncTest(new BenchRunner(BenchRunner.BenchMode.Set), go.Token); break; } case "watch": { // Bench Set RunAsyncTest(new BenchRunner(BenchRunner.BenchMode.Watch), go.Token); break; } } break; } case "msg": { switch (prm.ToLowerInvariant()) { case "producer": { // Queue Producer RunAsyncTest(new MessageQueueRunner(PerfCounters.ProcessName + "[" + PerfCounters.ProcessId + "]", MessageQueueRunner.AgentRole.Producer, TimeSpan.FromMilliseconds(50), TimeSpan.FromMilliseconds(200)), go.Token); break; } case "worker": { // Queue Worker RunAsyncTest(new MessageQueueRunner(PerfCounters.ProcessName + "[" + PerfCounters.ProcessId + "]", MessageQueueRunner.AgentRole.Worker, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(10)), go.Token); break; } case "clear": { // Queue Clear RunAsyncTest(new MessageQueueRunner(PerfCounters.ProcessName + "[" + PerfCounters.ProcessId + "]", MessageQueueRunner.AgentRole.Clear, TimeSpan.Zero, TimeSpan.Zero), go.Token); break; } case "status": { // Queue Status RunAsyncTest(new MessageQueueRunner(PerfCounters.ProcessName + "[" + PerfCounters.ProcessId + "]", MessageQueueRunner.AgentRole.Status, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10)), go.Token); break; } } break; } case "leak": { // LeastTest switch (prm.ToLowerInvariant()) { case "fast": RunAsyncTest(new LeakTest(100, 100, 1000, TimeSpan.FromSeconds(0)), go.Token); break; case "slow": RunAsyncTest(new LeakTest(100, 100, 1000, TimeSpan.FromSeconds(30)), go.Token); break; default: RunAsyncTest(new LeakTest(100, 100, 1000, TimeSpan.FromSeconds(1)), go.Token); break; } break; } case "sampling": { // SamplingTest RunAsyncTest(new SamplerTest(0.1), go.Token); break; } case "q": case "x": case "quit": case "exit": { stop = true; break; } case "gc": { long before = GC.GetTotalMemory(false); Console.Write("Collecting garbage..."); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Console.WriteLine(" Done"); long after = GC.GetTotalMemory(false); Console.WriteLine("- before = " + before.ToString("N0")); Console.WriteLine("- after = " + after.ToString("N0")); Console.WriteLine("- delta = " + (before - after).ToString("N0")); break; } case "mem": { Console.WriteLine("Memory usage:"); Console.WriteLine("- Managed Mem : " + GC.GetTotalMemory(false).ToString("N0")); #if !NETCOREAPP Console.WriteLine("- Working Set : " + PerfCounters.WorkingSet.NextValue().ToString("N0") + " (peak " + PerfCounters.WorkingSetPeak.NextValue().ToString("N0") + ")"); Console.WriteLine("- Virtual Bytes: " + PerfCounters.VirtualBytes.NextValue().ToString("N0") + " (peak " + PerfCounters.VirtualBytesPeak.NextValue().ToString("N0") + ")"); Console.WriteLine("- Private Bytes: " + PerfCounters.PrivateBytes.NextValue().ToString("N0")); Console.WriteLine("- BytesInAlHeap: " + PerfCounters.ClrBytesInAllHeaps.NextValue().ToString("N0")); #endif break; } default: { Console.WriteLine(string.Format("Unknown command : '{0}'", trimmedCommand)); break; } } } } } finally { go.Cancel(); Fdb.Stop(); Console.WriteLine("Bye"); } }
public static IFdbDatabaseProviderBuilder WithConnectionString(this IFdbDatabaseProviderBuilder builder, FdbConnectionOptions options) { builder.Services.Configure <FdbDatabaseProviderOptions>(c => { c.ConnectionOptions = options; }); return(builder); }
private static async Task MainAsync(CancellationToken ct) { // change the path to the native lib if not default if (NATIVE_PATH != null) { Fdb.Options.SetNativeLibPath(NATIVE_PATH); } // uncomment this to enable network thread tracing // FdbCore.TracePath = Path.Combine(Path.GetTempPath(), "fdb"); int apiVersion = Fdb.GetMaxApiVersion(); Console.WriteLine("Max API Version: " + apiVersion); try { Console.WriteLine("Starting network thread..."); Fdb.Start(Fdb.GetDefaultApiVersion()); Console.WriteLine("> Up and running"); var settings = new FdbConnectionOptions() { ClusterFile = CLUSTER_FILE, Root = FdbPath.Parse("/Sandbox"), }; Console.WriteLine("Connecting to local cluster..."); using (var db = await Fdb.OpenAsync(settings, ct)) { Console.WriteLine("> Connected!"); // get coordinators var cf = await Fdb.System.GetCoordinatorsAsync(db, ct); Console.WriteLine("Coordinators: " + cf.ToString()); // clear everything using (var tr = await db.BeginTransactionAsync(ct)) { Console.WriteLine("Clearing subspace " + db.Root + " ..."); var subspace = await db.Root.Resolve(tr); tr.ClearRange(subspace); await tr.CommitAsync(); Console.WriteLine("> Database cleared"); } Console.WriteLine(); await TestSimpleTransactionAsync(db, ct); await BenchInsertSmallKeysAsync(db, N, 16, ct); // some guid await BenchInsertSmallKeysAsync(db, N, 60 * 4, ct); // one Int32 per minutes, over an hour await BenchInsertSmallKeysAsync(db, N, 512, ct); // small JSON payload await BenchInsertSmallKeysAsync(db, N / 5, 4096, ct); // typical small cunk size await BenchInsertSmallKeysAsync(db, N / 100, 65536, ct); // typical medium chunk size await BenchInsertSmallKeysAsync(db, 20, 100_000, ct); // Maximum value size (as of beta 1) // insert keys in parrallel await BenchConcurrentInsert(db, 1, 100, 512, ct); await BenchConcurrentInsert(db, 1, 1_000, 512, ct); await BenchConcurrentInsert(db, 1, 10_000, 512, ct); await BenchConcurrentInsert(db, 1, N, 16, ct); await BenchConcurrentInsert(db, 2, N, 16, ct); await BenchConcurrentInsert(db, 4, N, 16, ct); await BenchConcurrentInsert(db, 8, N, 16, ct); await BenchConcurrentInsert(db, 16, N, 16, ct); await BenchSerialWriteAsync(db, N, ct); await BenchSerialReadAsync(db, N, ct); await BenchConcurrentReadAsync(db, N, ct); await BenchClearAsync(db, N, ct); await BenchUpdateSameKeyLotsOfTimesAsync(db, 1000, ct); await BenchUpdateLotsOfKeysAsync(db, 1000, ct); await BenchBulkInsertThenBulkReadAsync(db, 100_000, 50, 128, ct); await BenchBulkInsertThenBulkReadAsync(db, 100_000, 128, 50, ct); await BenchBulkInsertThenBulkReadAsync(db, 1_000_000, 50, 128, ct); await BenchMergeSortAsync(db, 100, 3, 20, ct); await BenchMergeSortAsync(db, 1_000, 10, 100, ct); await BenchMergeSortAsync(db, 100, 100, 100, ct); await BenchMergeSortAsync(db, 100, 1_000, 100, ct); Console.WriteLine("time to say goodbye..."); } } finally { Console.WriteLine("### DONE ###"); Fdb.Stop(); } #if DEBUG Console.ReadLine(); #endif }