async Task Authenticate(string username, NpgsqlTimeout timeout, bool async, CancellationToken cancellationToken) { Log.Trace("Authenticating...", Id); timeout.CheckAndApply(this); var msg = Expect <AuthenticationRequestMessage>(await ReadMessage(async), this); switch (msg.AuthRequestType) { case AuthenticationRequestType.AuthenticationOk: return; case AuthenticationRequestType.AuthenticationCleartextPassword: await AuthenticateCleartext(username, async, cancellationToken); return; case AuthenticationRequestType.AuthenticationMD5Password: await AuthenticateMD5(username, ((AuthenticationMD5PasswordMessage)msg).Salt, async, cancellationToken); return; case AuthenticationRequestType.AuthenticationSASL: AuthenticationSASLMessage authmsg = (AuthenticationSASLMessage)msg; await AuthenticateSha256(authmsg.Salt, authmsg.Token, authmsg.Iteration, username, async, cancellationToken); return; case AuthenticationRequestType.AuthenticationGSS: case AuthenticationRequestType.AuthenticationSSPI: await AuthenticateGSS(async); return; case AuthenticationRequestType.AuthenticationGSSContinue: throw new NpgsqlException("Can't start auth cycle with AuthenticationGSSContinue"); default: throw new NotSupportedException($"Authentication method not supported (Received: {msg.AuthRequestType})"); } }
internal static async Task Bind(NpgsqlConnector connector, NpgsqlTimeout timeout, bool async) { // Note that there's a chicken and egg problem here - PostgresDatabase.Load below needs a functional // connector to load the types, hence the strange initialization code here var mapper = new ConnectorTypeMapper(connector); connector.TypeMapper = mapper; // If we've connected to this specific database before, we have a PostgresDatabase instance // (containing all type information) var connString = connector.ConnectionString; if (!DatabaseInfo.Cache.TryGetValue(connString, out var database)) { DatabaseInfo.Cache[connString] = database = await DatabaseInfo.Load(connector, timeout, async); } mapper.DatabaseInfo = database; mapper.BindTypes(); }
public ClusterInfo(ClusterState state, NpgsqlTimeout timeout, DateTime timeStamp) => (State, Timeout, TimeStamp) = (state, timeout, timeStamp);
public Task <NpgsqlDatabaseInfo?> Load(NpgsqlConnector conn, NpgsqlTimeout timeout, bool async) => Task.FromResult( conn.Settings.ServerCompatibilityMode == ServerCompatibilityMode.NoTypeLoading ? (NpgsqlDatabaseInfo) new PostgresMinimalDatabaseInfo(conn) : null );
/// <summary> /// Executes a potentially non-cancellable <see cref="Task"/> while allowing to timeout and/or cancel awaiting for it. /// If the given task does not complete within <paramref name="timeout"/>, a <see cref="TimeoutException"/> is thrown. /// The executed <see cref="Task"/> may be left in an incomplete state after the <see cref="Task"/> that this method returns completes dues to timeout and/or cancellation request. /// The method guarantees that the abandoned, incomplete <see cref="Task"/> is not going to produce <see cref="TaskScheduler.UnobservedTaskException"/> event if it fails later. /// </summary> /// <param name="getTaskFunc">Gets the <see cref="Task"/> for execution with a combined <see cref="CancellationToken"/> that attempts to cancel the <see cref="Task"/> in an event of the timeout or external cancellation request.</param> /// <param name="timeout">The timeout after which the <see cref="Task"/> should be faulted with a <see cref="TimeoutException"/> if it hasn't otherwise completed.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for a cancellation request.</param> /// <returns>The <see cref="Task"/> representing the asynchronous wait.</returns> internal static async Task ExecuteAsync(Func <CancellationToken, Task> getTaskFunc, NpgsqlTimeout timeout, CancellationToken cancellationToken) { using var combinedCts = timeout.IsSet ? CancellationTokenSource.CreateLinkedTokenSource(cancellationToken) : null; var task = getTaskFunc(combinedCts?.Token ?? cancellationToken); try { try { await task.WaitAsync(timeout.CheckAndGetTimeLeft(), cancellationToken); } catch (TimeoutException) when(!task !.IsCompleted) { // Attempt to stop the Task in progress. combinedCts?.Cancel(); throw; } } catch { // Prevent unobserved Task notifications by observing the failed Task exception. // To test: comment the next line out and re-run TaskExtensionsTest.DelayedFaultedTaskCancellation. _ = task.ContinueWith(t => _ = t.Exception, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Current); throw; } } }
/// <summary> /// Executes a potentially non-cancellable <see cref="Task{TResult}"/> while allowing to timeout and/or cancel awaiting for it. /// If the given task does not complete within <paramref name="timeout"/>, a <see cref="TimeoutException"/> is thrown. /// The executed <see cref="Task{TResult}"/> may be left in an incomplete state after the <see cref="Task{TResult}"/> that this method returns completes dues to timeout and/or cancellation request. /// The method guarantees that the abandoned, incomplete <see cref="Task{TResult}"/> is not going to produce <see cref="TaskScheduler.UnobservedTaskException"/> event if it fails later. /// </summary> /// <param name="getTaskFunc">Gets the <see cref="Task{TResult}"/> for execution with a combined <see cref="CancellationToken"/> that attempts to cancel the <see cref="Task{TResult}"/> in an event of the timeout or external cancellation request.</param> /// <param name="timeout">The timeout after which the <see cref="Task{TResult}"/> should be faulted with a <see cref="TimeoutException"/> if it hasn't otherwise completed.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for a cancellation request.</param> /// <typeparam name="TResult">The result <see cref="Type"/>.</typeparam> /// <returns>The <see cref="Task{TResult}"/> representing the asynchronous wait.</returns> internal static async Task <TResult> ExecuteAsync <TResult>(Func <CancellationToken, Task <TResult> > getTaskFunc, NpgsqlTimeout timeout, CancellationToken cancellationToken) { Task <TResult>?task = default; await ExecuteAsync(ct => (Task)(task = getTaskFunc(ct)), timeout, cancellationToken); return(await task !); }