Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Pluggable foundation blocks for building distributed apps.

License

NotificationsYou must be signed in to change notification settings

FoundatioFx/Foundatio

Repository files navigation

FoundatioFoundatio

Build statusNuGet Versionfeedz.ioDiscord

Pluggable foundation blocks for building loosely coupled distributed apps.

Includes implementations in Redis, Azure, AWS, RabbitMQ, Kafka and in memory (for development).

Why Foundatio?

When building several big cloud applications we found a lack of great solutions (that's not to say there isn't solutions out there) for many key pieces to building scalable distributed applications while keeping the development experience simple. Here are a few examples of why we built and use Foundatio:

  • Wanted to build against abstract interfaces so that we could easily change implementations.
  • Wanted the blocks to be dependency injection friendly.
  • Caching: We were initially using an open source Redis cache client but then it turned into a commercial product with high licensing costs. Not only that, but there weren't any in memory implementations so every developer was required to set up and configure Redis.
  • Message Bus: We initially looked atNServiceBus (great product) but it had high licensing costs (they have to eat too) but was not OSS friendly. We also looked intoMassTransit (another great product) but found Azure support lacking at the time and local set up a pain (for in memory). We wanted a simple message bus that just worked locally or in the cloud.
  • Storage: We couldn't find any existing project that was decoupled and supported in memory, file storage or Azure Blob Storage.

To summarize, if you want pain free development and testing while allowing your app to scale, use Foundatio!

Implementations

Getting Started (Development)

Foundatio can be installed via theNuGet package manager. If you need help, pleaseopen an issue or join ourDiscord chat room. We’re always here to help if you have any questions!

This section is for development purposes only! If you are trying to use the Foundatio libraries, please get them from NuGet.

  1. You will need to haveVisual Studio Code installed.
  2. Open theFoundatio.sln Visual Studio solution file.

Using Foundatio

The sections below contain a small subset of what's possible with Foundatio. We recommend taking a peek at the source code for more information. Please let us know if you have any questions or need assistance!

Caching allows you to store and access data lightning fast, saving you exspensive operations to create or get data. We provide four different cache implementations that derive from theICacheClient interface:

  1. InMemoryCacheClient: An in memory cache client implementation. This cache implementation is only valid for the lifetime of the process. It's worth noting that the in memory cache client has the ability to cache the last X items via theMaxItems property. We use this inExceptionless to onlykeep the last 250 resolved geoip results.
  2. HybridCacheClient: This cache implementation uses both anICacheClient and theInMemoryCacheClient and uses anIMessageBus to keep the cache in sync across processes. This can lead tohuge wins in performance as you are saving a serialization operation and a call to the remote cache if the item exists in the local cache.
  3. RedisCacheClient: A Redis cache client implementation.
  4. RedisHybridCacheClient: An implementation ofHybridCacheClient that uses theRedisCacheClient asICacheClient and theRedisMessageBus asIMessageBus.
  5. ScopedCacheClient: This cache implementation takes an instance ofICacheClient and a stringscope. The scope is prefixed onto every cache key. This makes it really easy to scope all cache keys and remove them with ease.

Sample

usingFoundatio.Caching;ICacheClientcache=newInMemoryCacheClient();awaitcache.SetAsync("test",1);varvalue=awaitcache.GetAsync<int>("test");

Queues offer First In, First Out (FIFO) message delivery. We provide four different queue implementations that derive from theIQueue interface:

  1. InMemoryQueue: An in memory queue implementation. This queue implementation is only valid for the lifetime of the process.
  2. RedisQueue: An Redis queue implementation.
  3. AzureServiceBusQueue: An Azure Service Bus Queue implementation.
  4. AzureStorageQueue: An Azure Storage Queue implementation.
  5. SQSQueue: An AWS SQS implementation.

Sample

usingFoundatio.Queues;IQueue<SimpleWorkItem>queue=newInMemoryQueue<SimpleWorkItem>();awaitqueue.EnqueueAsync(newSimpleWorkItem{Data="Hello"});varworkItem=awaitqueue.DequeueAsync();

Locks ensure a resource is only accessed by one consumer at any given time. We provide two different locking implementations that derive from theILockProvider interface:

  1. CacheLockProvider: A lock implementation that uses cache to communicate between processes.
  2. ThrottlingLockProvider: A lock implementation that only allows a certain amount of locks through. You could use this to throttle api calls to some external service and it will throttle them across all processes asking for that lock.
  3. ScopedLockProvider: This lock implementation takes an instance ofILockProvider and a stringscope. The scope is prefixed onto every lock key. This makes it really easy to scope all locks and release them with ease.

It's worth noting that all lock providers take aICacheClient. This allows you to ensure your code locks properly across machines.

Sample

usingFoundatio.Lock;ILockProviderlocker=newCacheLockProvider(newInMemoryCacheClient(),newInMemoryMessageBus());vartestLock=awaitlocker.AcquireAsync("test");// ...awaittestLock.ReleaseAsync();ILockProviderthrottledLocker=newThrottlingLockProvider(newInMemoryCacheClient(),1,TimeSpan.FromMinutes(1));varthrottledLock=awaitthrottledLocker.AcquireAsync("test");// ...awaitthrottledLock.ReleaseAsync();

Allows you to publish and subscribe to messages flowing through your application. We provide four different message bus implementations that derive from theIMessageBus interface:

  1. InMemoryMessageBus: An in memory message bus implementation. This message bus implementation is only valid for the lifetime of the process.
  2. RedisMessageBus: A Redis message bus implementation.
  3. RabbitMQMessageBus: A RabbitMQ implementation.
  4. KafkaMessageBus: A Kafka implementation.
  5. AzureServiceBusMessageBus: An Azure Service Bus implementation.

Sample

usingFoundatio.Messaging;IMessageBusmessageBus=newInMemoryMessageBus();awaitmessageBus.SubscribeAsync<SimpleMessageA>(msg=>{// Got message});awaitmessageBus.PublishAsync(newSimpleMessageA{Data="Hello"});

Allows you to run a long running process (in process or out of process) without worrying about it being terminated prematurely. We provide three different ways of defining a job, based on your use case:

  1. Jobs: All jobs must derive from theIJob interface. We also have aJobBase base class you can derive from which provides a JobContext and logging. You can then run jobs by callingRunAsync() on the job or by creating a instance of theJobRunner class and calling one of the Run methods. The JobRunner can be used to easily run your jobs as Azure Web Jobs.

Sample

usingFoundatio.Jobs;publicclassHelloWorldJob:JobBase{publicintRunCount{get;set;}protectedoverrideTask<JobResult>RunInternalAsync(JobContextcontext){RunCount++;returnTask.FromResult(JobResult.Success);}}
varjob=newHelloWorldJob();awaitjob.RunAsync();// job.RunCount = 1;awaitjob.RunContinuousAsync(iterationLimit:2);// job.RunCount = 3;awaitjob.RunContinuousAsync(cancellationToken:newCancellationTokenSource(10).Token);// job.RunCount > 10;
  1. Queue Processor Jobs: A queue processor job works great for working with jobs that will be driven from queued data. Queue Processor jobs must derive fromQueueJobBase<T> class. You can then run jobs by callingRunAsync() on the job or passing it to theJobRunner class. The JobRunner can be used to easily run your jobs as Azure Web Jobs.

Sample

usingFoundatio.Jobs;publicclassHelloWorldQueueJob:QueueJobBase<HelloWorldQueueItem>{publicintRunCount{get;set;}publicHelloWorldQueueJob(IQueue<HelloWorldQueueItem>queue):base(queue){}protectedoverrideTask<JobResult>ProcessQueueEntryAsync(QueueEntryContext<HelloWorldQueueItem>context){RunCount++;returnTask.FromResult(JobResult.Success);}}publicclassHelloWorldQueueItem{publicstringMessage{get;set;}}
// Register the queue for HelloWorldQueueItem.container.AddSingleton<IQueue<HelloWorldQueueItem>>(s=>newInMemoryQueue<HelloWorldQueueItem>());// To trigger the job we need to queue the HelloWorldWorkItem message.// This assumes that we injected an instance of IQueue<HelloWorldWorkItem> queueIJobjob=newHelloWorldQueueJob();awaitjob.RunAsync();// job.RunCount = 0; The RunCount wasn't incremented because we didn't enqueue any data.awaitqueue.EnqueueAsync(newHelloWorldWorkItem{Message="Hello World"});awaitjob.RunAsync();// job.RunCount = 1;awaitqueue.EnqueueAsync(newHelloWorldWorkItem{Message="Hello World"});awaitqueue.EnqueueAsync(newHelloWorldWorkItem{Message="Hello World"});awaitjob.RunUntilEmptyAsync();// job.RunCount = 3;
  1. Work Item Jobs: A work item job will run in a job pool among other work item jobs. This type of job works great for things that don't happen often but should be in a job (Example: Deleting an entity that has many children.). It will be triggered when you publish a message on themessage bus. The job must derive from theWorkItemHandlerBase class. You can then run all shared jobs viaJobRunner class. The JobRunner can be used to easily run your jobs as Azure Web Jobs.

Sample

usingSystem.Threading.Tasks;usingFoundatio.Jobs;publicclassHelloWorldWorkItemHandler:WorkItemHandlerBase{publicoverrideasyncTaskHandleItemAsync(WorkItemContextctx){varworkItem=ctx.GetData<HelloWorldWorkItem>();// We can report the progress over the message bus easily.// To receive these messages just inject IMessageSubscriber// and Subscribe to messages of type WorkItemStatusawaitctx.ReportProgressAsync(0,"Starting Hello World Job");awaitTask.Delay(TimeSpan.FromSeconds(2.5));awaitctx.ReportProgressAsync(50,"Reading value");awaitTask.Delay(TimeSpan.FromSeconds(.5));awaitctx.ReportProgressAsync(70,"Reading value");awaitTask.Delay(TimeSpan.FromSeconds(.5));awaitctx.ReportProgressAsync(90,"Reading value.");awaitTask.Delay(TimeSpan.FromSeconds(.5));awaitctx.ReportProgressAsync(100,workItem.Message);}}publicclassHelloWorldWorkItem{publicstringMessage{get;set;}}
// Register the shared job.varhandlers=newWorkItemHandlers();handlers.Register<HelloWorldWorkItem,HelloWorldWorkItemHandler>();// Register the handlers with dependency injection.container.AddSingleton(handlers);// Register the queue for WorkItemData.container.AddSingleton<IQueue<WorkItemData>>(s=>newInMemoryQueue<WorkItemData>());// The job runner will automatically look for and run all registered WorkItemHandlers.newJobRunner(container.GetRequiredService<WorkItemJob>(),instanceCount:2).RunInBackground();
// To trigger the job we need to queue the HelloWorldWorkItem message.// This assumes that we injected an instance of IQueue<WorkItemData> queue// NOTE: You may have noticed that HelloWorldWorkItem doesn't derive from WorkItemData.// Foundatio has an extension method that takes the model you post and serializes it to the// WorkItemData.Data property.awaitqueue.EnqueueAsync(newHelloWorldWorkItem{Message="Hello World"});

We provide different file storage implementations that derive from theIFileStorage interface:

  1. InMemoryFileStorage: An in memory file implementation. This file storage implementation is only valid for the lifetime of the process.
  2. FolderFileStorage: An file storage implementation that uses the hard drive for storage.
  3. AzureFileStorage: An Azure Blob storage implementation.
  4. S3FileStorage: An AWS S3 file storage implementation.
  5. RedisFileStorage: An Redis file storage implementation.
  6. MinioFileStorage An Minio file storage implementation.
  7. AliyunFileStorage: An Aliyun file storage implementation.
  8. SshNetFileStorage: An SFTP file storage implementation.

We recommend using all of theIFileStorage implementations as singletons.

Sample

usingFoundatio.Storage;IFileStoragestorage=newInMemoryFileStorage();awaitstorage.SaveFileAsync("test.txt","test");stringcontent=awaitstorage.GetFileContentsAsync("test.txt")

We provide five implementations that derive from theIMetricsClient interface:

  1. InMemoryMetricsClient: An in memory metrics implementation.
  2. RedisMetricsClient: An Redis metrics implementation.
  3. StatsDMetricsClient: An statsd metrics implementation.
  4. MetricsNETClient: AnMetrics.NET implementation.
  5. AppMetricsClient: AnAppMetrics implementation.
  6. CloudWatchMetricsClient: AnAWS CloudWatch implementation.

We recommend using all of theIMetricsClient implementations as singletons.

Sample

IMetricsClientmetrics=newInMemoryMetricsClient();metrics.Counter("c1");metrics.Gauge("g1",2.534);metrics.Timer("t1",50788);

Sample Application

We have bothslides and asample application that shows off how to use Foundatio.

Thanks to all the people who have contributed

contributors


[8]ページ先頭

©2009-2025 Movatter.jp