Skip to content
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
6 changes: 3 additions & 3 deletions src/Ephemerally.Azure.Cosmos/CosmosContainerEphemeral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ public class CosmosContainerEphemeral : Ephemeral<Container>
{
public CosmosContainerEphemeral(
Container container,
EphemeralOptions options = default) :
base(container, x => x.Id, options.OrDefault())
EphemeralOptions options = null) :
base(container, options.OrDefault())
{ }

protected override Task CleanupSelfAsync() =>
Value.Database.TryDeleteContainerAsync(Metadata.FullName);
Value.Database.TryDeleteContainerAsync(Value.Id);

protected override Task CleanupAllAsync() =>
Value.Database.TryCleanupContainersAsync();
Expand Down
6 changes: 3 additions & 3 deletions src/Ephemerally.Azure.Cosmos/CosmosDatabaseEphemeral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ public class CosmosDatabaseEphemeral : Ephemeral<Database>
{
public CosmosDatabaseEphemeral(
Database database,
EphemeralOptions options = default)
: base(database, x => x.Id, options.OrDefault())
EphemeralOptions options = null)
: base(database, options.OrDefault())
{ }

protected override Task CleanupSelfAsync() =>
Value.Client.TryDeleteDatabaseAsync(Metadata.FullName);
Value.Client.TryDeleteDatabaseAsync(Value.Id);

protected override Task CleanupAllAsync() =>
Value.Client.TryCleanupDatabasesAsync();
Expand Down
52 changes: 28 additions & 24 deletions src/Ephemerally.Azure.Cosmos/InternalExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Microsoft.Azure.Cosmos;
using System.Diagnostics;
// ReSharper disable MemberCanBePrivate.Global

namespace Ephemerally.Azure.Cosmos;

Expand Down Expand Up @@ -56,16 +57,16 @@ internal static async Task<bool> TryDeleteDatabaseAsync(this CosmosClient client
}

internal static bool IsExpired(this DatabaseProperties container) =>
container.Id.GetContainerMetadata().IsExpired();
container.Id.GetNamedMetadata().IsExpired();

internal static bool IsExpired(this Database container) =>
container.Id.GetContainerMetadata().IsExpired();
container.Id.GetNamedMetadata().IsExpired();

internal static bool IsExpired(this ContainerProperties container) =>
container.Id.GetContainerMetadata().IsExpired();
container.Id.GetNamedMetadata().IsExpired();

internal static bool IsExpired(this Container container) =>
container.Id.GetContainerMetadata().IsExpired();
container.Id.GetNamedMetadata().IsExpired();

internal static async Task<IEnumerable<DatabaseProperties>> GetExpiredDatabasesAsync(this CosmosClient client)
{
Expand All @@ -87,24 +88,35 @@ internal static async Task TryCleanupDatabasesAsync(this CosmosClient client)
}
}

internal static async Task<bool> TryDeleteContainerAsync(this Database database, string containerId)
extension(Database database)
{
try
internal async Task<bool> TryDeleteContainerAsync(string containerId)
{
await database.GetContainer(containerId).DeleteContainerAsync().ConfigureAwait(false);
return true;
try
{
await database.GetContainer(containerId).DeleteContainerAsync().ConfigureAwait(false);
return true;
}
catch (Exception ex)
{
Debug.WriteLine(ex.ToString());
return false;
}
}
catch (Exception ex)

internal async Task<IEnumerable<ContainerProperties>> GetExpiredContainersAsync()
{
Debug.WriteLine(ex.ToString());
return false;
using var iterator = database.GetContainerQueryIterator<ContainerProperties>();
return await iterator.GetExpiredContainersAsync().ToListAsync().ConfigureAwait(false);
}
}

internal static async Task<IEnumerable<ContainerProperties>> GetExpiredContainersAsync(this Database database)
{
using var iterator = database.GetContainerQueryIterator<ContainerProperties>();
return await iterator.GetExpiredContainersAsync().ToListAsync().ConfigureAwait(false);
internal async Task TryCleanupContainersAsync()
{
foreach (var container in await database.GetExpiredContainersAsync().ConfigureAwait(false))
{
await database.TryDeleteContainerAsync(container.Id).ConfigureAwait(false);
}
}
}

internal static IAsyncEnumerable<ContainerProperties> GetExpiredContainersAsync(this FeedIterator<ContainerProperties> iterator) =>
Expand All @@ -113,14 +125,6 @@ internal static IAsyncEnumerable<ContainerProperties> GetExpiredContainersAsync(
.SelectResources()
.Where(IsExpired);

internal static async Task TryCleanupContainersAsync(this Database database)
{
foreach (var container in await database.GetExpiredContainersAsync().ConfigureAwait(false))
{
await database.TryDeleteContainerAsync(container.Id).ConfigureAwait(false);
}
}

internal static IAsyncEnumerable<T> OnEach<T>(this IAsyncEnumerable<T> enumerable, Action<T> action) =>
enumerable.Select(x =>
{
Expand Down
24 changes: 12 additions & 12 deletions src/Ephemerally.Azure.Cosmos/PublicExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,28 @@ public static class PublicExtensions
{
private const string DefaultPartitionKeyPath = "/id";

public static EphemeralCosmosDatabase ToEphemeral(this Database database, EphemeralOptions options = default) =>
public static EphemeralCosmosDatabase ToEphemeral(this Database database, EphemeralOptions options = null) =>
new(new CosmosDatabaseEphemeral(database, options));

public static EphemeralCosmosContainer ToEphemeral(this Container container, EphemeralOptions options = default) =>
public static EphemeralCosmosContainer ToEphemeral(this Container container, EphemeralOptions options = null) =>
new(new CosmosContainerEphemeral(container, options));

public static async Task<EphemeralCosmosDatabase> CreateEphemeralDatabaseAsync(
this CosmosClient client,
EphemeralCreationOptions options = default)
EphemeralCreationOptions options = null)
{
var metadata = options.OrDefault().GetNewMetadata();
var metadata = options.OrDefault().GetNewNamedMetadata();
var response = await client.CreateDatabaseIfNotExistsAsync(metadata.FullName).ConfigureAwait(false);
return client.GetDatabase(response.Resource.Id).ToEphemeral(options);
}

public static async Task<EphemeralCosmosContainer> CreateEphemeralContainerAsync(
this Database database,
EphemeralCreationOptions options = default,
ContainerProperties containerProperties = default,
ThroughputProperties throughputProperties = default)
EphemeralCreationOptions options = null,
ContainerProperties containerProperties = null,
ThroughputProperties throughputProperties = null)
{
var metadata = options.OrDefault().GetNewMetadata();
var metadata = options.OrDefault().GetNewNamedMetadata();
containerProperties ??= new();
containerProperties.Id ??= metadata.FullName;
containerProperties.PartitionKeyPath ??= DefaultPartitionKeyPath;
Expand All @@ -38,14 +38,14 @@ public static async Task<EphemeralCosmosContainer> CreateEphemeralContainerAsync
}

public static IEphemeralMetadata GetEphemeralMetadata(this DatabaseProperties container) =>
container.Id.GetContainerMetadata();
container.Id.GetNamedMetadata();

public static IEphemeralMetadata GetEphemeralMetadata(this Database container) =>
container.Id.GetContainerMetadata();
container.Id.GetNamedMetadata();

public static IEphemeralMetadata GetEphemeralMetadata(this ContainerProperties container) =>
container.Id.GetContainerMetadata();
container.Id.GetNamedMetadata();

public static IEphemeralMetadata GetEphemeralMetadata(this Container container) =>
container.Id.GetContainerMetadata();
container.Id.GetNamedMetadata();
}
11 changes: 7 additions & 4 deletions src/Ephemerally.Redis.Xunit/PublicExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ namespace Ephemerally;

public static class PublicExtensions
{
public static ConnectionMultiplexer GetMultiplexer(this IRedisInstanceFixture fixture) =>
ConnectionMultiplexer.Connect(fixture.ConnectionString);
extension(IRedisInstanceFixture fixture)
{
public ConnectionMultiplexer GetMultiplexer() =>
ConnectionMultiplexer.Connect(fixture.ConnectionString);

public static Task<ConnectionMultiplexer> GetMultiplexerAsync(this IRedisInstanceFixture fixture) =>
ConnectionMultiplexer.ConnectAsync(fixture.ConnectionString);
public Task<ConnectionMultiplexer> GetMultiplexerAsync() =>
ConnectionMultiplexer.ConnectAsync(fixture.ConnectionString);
}
}
38 changes: 23 additions & 15 deletions src/Ephemerally.Redis/PublicExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ namespace Ephemerally;

public static class PublicExtensions
{
public static IEphemeralRedisDatabase AsEphemeral(this IDatabase database) =>
database is null or IEphemeralRedisDatabase
? (IEphemeralRedisDatabase)database
: database.ToEphemeral();
extension(IDatabase database)
{
public IEphemeralRedisDatabase AsEphemeral() =>
database is null or IEphemeralRedisDatabase
? (IEphemeralRedisDatabase)database
: database.ToEphemeral();

public static IEphemeralRedisDatabase ToEphemeral(this IDatabase database) =>
new EphemeralRedisDatabase(new RedisDatabaseEphemeral(database));
public IEphemeralRedisDatabase ToEphemeral() =>
new EphemeralRedisDatabase(new RedisDatabaseEphemeral(database));
}

public static IEphemeralRedisDatabase GetEphemeralDatabase(
this IConnectionMultiplexer multiplexer,
Expand All @@ -22,22 +25,27 @@ public static IEphemeralRedisDatabase GetEphemeralDatabase(

#region EphemeralConnectionMultiplexer

public static EphemeralConnectionMultiplexer AsEphemeralMultiplexer(this IConnectionMultiplexer multiplexer) =>
multiplexer as EphemeralConnectionMultiplexer ?? multiplexer.ToEphemeralMultiplexer();
extension(IConnectionMultiplexer multiplexer)
{
public EphemeralConnectionMultiplexer AsEphemeralMultiplexer() =>
multiplexer as EphemeralConnectionMultiplexer ?? multiplexer.ToEphemeralMultiplexer();

public static EphemeralConnectionMultiplexer ToEphemeralMultiplexer(this IConnectionMultiplexer multiplexer) =>
new(multiplexer);
public EphemeralConnectionMultiplexer ToEphemeralMultiplexer() =>
new(multiplexer);
}

#endregion

#region PooledConnectionMultiplexer

public static PooledConnectionMultiplexer AsPooledMultiplexer(this IConnectionMultiplexer multiplexer) =>
multiplexer as PooledConnectionMultiplexer ?? multiplexer.ToPooledMultiplexer();
extension(IConnectionMultiplexer multiplexer)
{
public PooledConnectionMultiplexer AsPooledMultiplexer() =>
multiplexer as PooledConnectionMultiplexer ?? multiplexer.ToPooledMultiplexer();

public static PooledConnectionMultiplexer ToPooledMultiplexer(this IConnectionMultiplexer multiplexer) =>
new(multiplexer);

public PooledConnectionMultiplexer ToPooledMultiplexer() =>
new(multiplexer);
}

#endregion
}
2 changes: 1 addition & 1 deletion src/Ephemerally.Redis/RedisDatabaseEphemeral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Ephemerally.Redis;

public class RedisDatabaseEphemeral(IDatabase value) : Ephemeral<IDatabase>(value, x => x.Database.ToString(), EphemeralCreationOptions),
public class RedisDatabaseEphemeral(IDatabase value) : Ephemeral<IDatabase>(value, EphemeralCreationOptions),
IDisposable
{
private static readonly EphemeralCreationOptions EphemeralCreationOptions = new()
Expand Down
7 changes: 0 additions & 7 deletions src/Ephemerally/CreationCachingBehavior.cs

This file was deleted.

13 changes: 3 additions & 10 deletions src/Ephemerally/Ephemeral.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,14 @@ public abstract class Ephemeral<TValue> : IEphemeral<TValue>
private bool _disposed;

private readonly EphemeralOptions _options;
private readonly EphemeralMetadata _metadata;
private readonly TValue _object;

private string FullName => _metadata.FullName;
public DateTimeOffset Expiration => _metadata.Expiration!.Value;
public IEphemeralMetadata Metadata => _metadata;

protected Ephemeral(TValue value, Func<TValue, string> getFullName, EphemeralOptions options)
protected Ephemeral(TValue value, EphemeralOptions options)
{
_object = value;
Value = value;
_options = options;
_metadata = EphemeralMetadata.Parse(getFullName(value));
}

public TValue Value => _object ?? throw new InvalidOperationException("The object has not been created yet.");
public TValue Value => field ?? throw new InvalidOperationException("The object has not been created yet.");

/// <summary>
/// In an overridden implementation, this method should delete the TObject.
Expand Down
1 change: 0 additions & 1 deletion src/Ephemerally/IEphemeralMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ namespace Ephemerally;

public interface IEphemeralMetadata
{
string FullName { get; }
DateTimeOffset? Expiration { get; }
}
27 changes: 15 additions & 12 deletions src/Ephemerally/InternalExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@ internal static class InternalExtensions
internal static T OrDefault<T>(this T options) where T : EphemeralOptions, new() =>
options ?? new T();

public static async ValueTask<bool> TryDisposeAsync<T>(this T self) where T : class
extension<T>(T self) where T : class
{
if (self is not IAsyncDisposable disposable)
return false;
public async ValueTask<bool> TryDisposeAsync()
{
if (self is not IAsyncDisposable disposable)
return false;

await disposable.DisposeAsync().ConfigureAwait(false);
return true;
}
await disposable.DisposeAsync().ConfigureAwait(false);
return true;
}

public static bool TryDispose<T>(this T self) where T : class
{
if (self is not IDisposable disposable)
return false;
public bool TryDispose()
{
if (self is not IDisposable disposable)
return false;

disposable.Dispose();
return true;
disposable.Dispose();
return true;
}
}
}
Loading
Loading