foundatio

Foundatio provides pluggable infrastructure abstractions. Use context7 MCP for complete documentation.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "foundatio" with this command: npx skills add exceptionless/exceptionless/exceptionless-exceptionless-foundatio

Foundatio

Foundatio provides pluggable infrastructure abstractions. Use context7 MCP for complete documentation.

Documentation: Use context7 to fetch current Foundatio API docs and examples.

Core Abstractions

Interface Purpose In-Memory Production

ICacheClient

Distributed caching InMemoryCacheClient

Redis

IQueue<T>

Message queuing InMemoryQueue<T>

Redis/SQS

IMessageBus

Pub/sub messaging InMemoryMessageBus

Redis

IFileStorage

File storage InMemoryFileStorage

S3/Azure

ILockProvider

Distributed locking InMemoryLockProvider

Redis

IResiliencePolicyProvider

Retry/circuit breaker N/A Polly-based

ICacheClient

// From src/Exceptionless.Core/Services/UsageService.cs public class UsageService { private readonly ICacheClient _cache;

public async Task&#x3C;int> GetUsageAsync(string organizationId, DateTime bucketUtc)
{
    var key = GetBucketTotalCacheKey(bucketUtc, organizationId);
    var result = await _cache.GetAsync&#x3C;int>(key);
    return result.HasValue ? result.Value : 0;
}

public async Task IncrementUsageAsync(string organizationId, DateTime bucketUtc, int count)
{
    var key = GetBucketTotalCacheKey(bucketUtc, organizationId);
    await _cache.IncrementAsync(key, count);

    // Track org in set for later processing
    await _cache.ListAddAsync(GetOrganizationSetKey(bucketUtc), organizationId);
}

}

IQueue

Queue items for background processing:

// Enqueue await _queue.EnqueueAsync(new EventPost { OrganizationId = orgId, ProjectId = projectId, FilePath = path });

IMessageBus

Pub/sub for real-time notifications:

// From src/Exceptionless.Web/Hubs/MessageBusBroker.cs await _subscriber.SubscribeAsync<EntityChanged>(OnEntityChangedAsync, shutdownToken); await _subscriber.SubscribeAsync<PlanChanged>(OnPlanChangedAsync, shutdownToken);

// Publishing await _messagePublisher.PublishAsync(new EntityChanged { ChangeType = ChangeType.Saved, Type = nameof(Organization), Id = organization.Id });

Jobs

QueueJobBase - Queue Processing

// From src/Exceptionless.Core/Jobs/EventPostsJob.cs [Job(Description = "Processes queued events.", InitialDelay = "2s")] public class EventPostsJob : QueueJobBase<EventPost> { public EventPostsJob( IQueue<EventPost> queue, TimeProvider timeProvider, IResiliencePolicyProvider resiliencePolicyProvider, ILoggerFactory loggerFactory) : base(queue, timeProvider, resiliencePolicyProvider, loggerFactory) { AutoComplete = false; // Manual completion after processing }

protected override async Task&#x3C;JobResult> ProcessQueueEntryAsync(QueueEntryContext&#x3C;EventPost> context)
{
    var entry = context.QueueEntry;
    using var _ = _logger.BeginScope(new ExceptionlessState()
        .Organization(entry.Value.OrganizationId)
        .Project(entry.Value.ProjectId));

    // Process the event...
    await entry.CompleteAsync();
    return JobResult.Success;
}

}

IJob - Scheduled Jobs

// From src/Exceptionless.Core/Jobs/CleanupDataJob.cs [Job(Description = "Deletes old data.", InitialDelay = "1m", Interval = "1h")] public class CleanupDataJob : IJob { public async Task<JobResult> RunAsync(CancellationToken cancellationToken = default) { await CleanupOrganizationsAsync(cancellationToken); await CleanupProjectsAsync(cancellationToken); return JobResult.Success; } }

Job Attributes

[Job( Description = "Job description", InitialDelay = "2s", // Delay before first run Interval = "5m", // Run every 5 minutes IterationLimit = 1, // Run once then stop IsContinuous = true // Keep running )]

Resilience with IResiliencePolicyProvider

IResiliencePolicyProvider provides retry policies for Foundatio components:

// Registration in Bootstrapper services.AddSingleton<IResiliencePolicyProvider, ResiliencePolicyProvider>();

All queue jobs inherit resilience via base class:

// From src/Exceptionless.Core/Jobs/EventPostsJob.cs public class EventPostsJob : QueueJobBase<EventPost> { public EventPostsJob( IQueue<EventPost> queue, TimeProvider timeProvider, IResiliencePolicyProvider resiliencePolicyProvider, ILoggerFactory loggerFactory) : base(queue, timeProvider, resiliencePolicyProvider, loggerFactory) { AutoComplete = false; // Manual completion for control }

protected override async Task&#x3C;JobResult> ProcessQueueEntryAsync(QueueEntryContext&#x3C;EventPost> context)
{
    var entry = context.QueueEntry;
    try
    {
        // Process...
        await entry.CompleteAsync();
        return JobResult.Success;
    }
    catch (Exception ex) when (ex is ValidationException or MiniValidatorException)
    {
        // Don't retry validation errors
        await entry.CompleteAsync();
        return JobResult.Success;
    }
}

}

Components configured with resilience:

// From src/Exceptionless.Core/Bootstrapper.cs services.AddSingleton<CacheLockProvider>(s => new CacheLockProvider( s.GetRequiredService<ICacheClient>(), s.GetRequiredService<IMessageBus>(), s.GetRequiredService<TimeProvider>(), s.GetRequiredService<IResiliencePolicyProvider>(), s.GetRequiredService<ILoggerFactory>() ));

Queue entries can be retried via AbandonAsync() or completed via CompleteAsync() .

Repositories

Foundatio.Repositories provides Elasticsearch integration:

// From src/Exceptionless.Core/Repositories/Base/RepositoryBase.cs public abstract class RepositoryBase<T> : ElasticRepositoryBase<T> { // Automatic change notifications via IMessageBus protected override Task PublishChangeTypeMessageAsync( ChangeType changeType, T? document, IDictionary<string, object>? data = null) { return PublishMessageAsync(CreateEntityChanged(changeType, document)); } }

Repository options:

// Cache results await _repository.GetByIdAsync(id, o => o.Cache());

// Immediate consistency (for tests) await _repository.AddAsync(entity, o => o.ImmediateConsistency());

Testing

Use in-memory implementations for tests:

services.AddSingleton<ICacheClient, InMemoryCacheClient>(); services.AddSingleton<IMessageBus, InMemoryMessageBus>(); services.AddSingleton(typeof(IQueue<>), typeof(InMemoryQueue<>));

See backend-testing for ProxyTimeProvider patterns.

Resilience & Reliability

Build resilient systems that handle failures gracefully:

  • Expect failures: Network calls fail, resources exhaust, concurrent access races

  • Timeouts everywhere: Never wait indefinitely; use cancellation tokens

  • Retry with backoff: Use exponential backoff with jitter for transient failures

  • Graceful degradation: Return cached data, default values, or partial results when appropriate

  • Idempotency: Design operations to be safely retryable

  • Resource limits: Bound queues, caches, and buffers to prevent memory exhaustion

Retry Pattern

// Queue entries support automatic retry await entry.AbandonAsync(); // Return to queue for retry await entry.CompleteAsync(); // Mark as successfully processed

// Don't retry validation errors - they'll never succeed catch (Exception ex) when (ex is ValidationException or MiniValidatorException) { await entry.CompleteAsync(); // Don't retry return JobResult.Success; }

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

shadcn-svelte components

No summary provided by upstream source.

Repository SourceNeeds Review
General

tanstack-form

No summary provided by upstream source.

Repository SourceNeeds Review
General

.net conventions

No summary provided by upstream source.

Repository SourceNeeds Review