Skip to content

Commit

Permalink
Add support for wait_until_available.
Browse files Browse the repository at this point in the history
  • Loading branch information
dnwpark committed Jan 21, 2025
1 parent 7fba716 commit 03e6c2e
Showing 1 changed file with 107 additions and 0 deletions.
107 changes: 107 additions & 0 deletions src/EdgeDB.Net.Driver/EdgeDBConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,9 @@ void SetArgument(string name, string? value, EdgeDBConnection conn)

conn.TLSSecurity = result;
break;
case "wait_until_available":
conn.Timeout = ParseWaitUntilAvailable(value);
break;

default:
throw new FormatException($"Unexpected configuration option \"{name}\"");
Expand Down Expand Up @@ -574,6 +577,110 @@ public static EdgeDBConnection ResolveEdgeDBTOML()
}
}

private static readonly Regex _isoUnitlessHours = new Regex(
@"^(-?\d+|-?\d+\.\d*|-?\d*\.\d+)$",
RegexOptions.Compiled);
private static readonly Regex _isoTimeWithUnits = new Regex(
@"((?<Hours>-?\d+|-?\d+\.\d*|-?\d*\.\d+)H)?"
+ @"((?<Minutes>-?\d+|-?\d+\.\d*|-?\d*\.\d+)M)?"
+ @"((?<Seconds>-?\d+|-?\d+\.\d*|-?\d*\.\d+)S)?",
RegexOptions.Compiled);
private static readonly Regex _humanHours = new Regex(
@"(?:(?:\s|^)-\s*)?(?<time>\d*\.?\d*)\s*(?:h(?:\s|\d|\.|$)|hours?(?:\s|$))",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex _humanMinutes = new Regex(
@"(?:(?:\s|^)-\s*)?(?<time>\d*\.?\d*)\s*(?:m(?:\s|\d|\.|$)|minutes?(?:\s|$))",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex _humanSeconds = new Regex(
@"(?:(?:\s|^)-\s*)?(?<time>\d*\.?\d*)\s*(?:s(?:\s|\d|\.|$)|seconds?(?:\s|$))",
RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex _humanMilliseconds = new Regex(
@"(?:(?:\s|^)-\s*)?(?<time>\d*\.?\d*)\s*(?:ms(?:\s|\d|\.|$)|milliseconds?(?:\s|$))",
RegexOptions.Compiled | RegexOptions.IgnoreCase);

internal static uint ParseWaitUntilAvailable(string text)
{
string originalText = text;

if (text.StartsWith("PT"))
{
// ISO duration
text = text.Substring(2);
Match match = _isoUnitlessHours.Match(text);
if (match.Success)
{
double hours = double.Parse(match.Groups[0].Value);
return ((uint)(hours * 3600))* 1000;
}

match = _isoTimeWithUnits.Match(text);
Group? group;
if (match.Success)
{
uint time = 0;
if (match.Groups.TryGetValue("Hours", out group) && !string.IsNullOrEmpty(group.Value))
{
time += ((uint)(double.Parse(group.Value) * 3600)) * 1000;
}
if (match.Groups.TryGetValue("Minutes", out group) && !string.IsNullOrEmpty(group.Value))
{
time += ((uint)(double.Parse(group.Value) * 60)) * 1000;
}
if (match.Groups.TryGetValue("Seconds", out group) && !string.IsNullOrEmpty(group.Value))
{
time += ((uint)(double.Parse(group.Value) * 1)) * 1000;
}
return time;
}
}
else
{
// human duration
bool PopHumanDuration(Regex regex, uint factor, ref string text, out uint time)
{
Match match = regex.Match(text);
if (!match.Success || string.IsNullOrEmpty(match.Groups["time"].Value))
{
time = 0;
return false;
}

time = (uint)(double.Parse(match.Groups["time"].Value) * factor);
text.Replace(match.Groups[0].Value, "");
return true;
}

bool found = false;
uint time = 0;
if (PopHumanDuration(_humanHours, 3600, ref text, out uint hours))
{
found = true;
time += hours * 1000;
}
if (PopHumanDuration(_humanMinutes, 60, ref text, out uint minutes))
{
found = true;
time += minutes * 1000;
}
if (PopHumanDuration(_humanSeconds, 1, ref text, out uint seconds))
{
found = true;
time += seconds * 1000;
}
if (PopHumanDuration(_humanMilliseconds, 1, ref text, out uint milliseconds))
{
found = true;
time += seconds;
}
if (found)
{
return time;
}
}

throw new ConfigurationException($"invalid duration {originalText}");
}

private void ParseCloudInstanceName(string name, string? cloudProfile = null)
{
if (name.Length > DOMAIN_NAME_MAX_LEN)
Expand Down

0 comments on commit 03e6c2e

Please sign in to comment.