Skip to main content

CacheService.SetAsync

Reference

Task SetAsync<T>(string key, T value, int ttlSeconds = 604800)

Use SetAsync to store a value in cache under a logical key with a time-to-live (TTL). The default TTL is seven days (604800 seconds). Callers should provide a positive TTL where appropriate.

Parameters

  • key: Logical cache key. Do not include any environment-specific prefix. Keys are case-sensitive.
  • value: The value to store in cache. If value is null, the implementation may either remove the key or store a placeholder. check your environment's behavior.
  • ttlSeconds: Time-to-live in seconds. Defaults to 604800 (7 days). Must be a positive integer.

Returns

Task: Completes successfully when the value has been written to the cache backend.

Error Handling & Caveats

  • If key is null or empty, an ArgumentException is thrown.
  • If ttlSeconds is not positive, an ArgumentException is thrown.
  • If the cache backend is unavailable, the method may throw a backend-specific exception. Consider retry/backoff or a best-effort write approach for non-critical data.
  • Large values increase network and serialization cost; consider size limits and compression strategies.
  • Storing complex objects requires careful versioning to avoid deserialization problems for older readers.

Usage

// Store a short-lived instance (await if cache write is critical)
await CacheService.SetAsync($"Instance:{instanceId}", instance, ttlSeconds: 300);
// Store user profile for 1 hour (await if cache write is critical)
await CacheService.SetAsync($"User:{userId}", userProfile, ttlSeconds: 3600);
// Fire-and-forget cache set if failure is non-critical
_ = CacheService.SetAsync($"User:{userId}", userProfile, ttlSeconds: 60);
  • Use await when cache consistency is critical (e.g., after a database update, or when you must ensure the cache is updated before proceeding).
  • Skip await (fire-and-forget) only if cache write failure is acceptable and will not impact correctness or user experience.

Example: Best-effort cache set with logging

public async Task CacheUserProfileAsync(Guid userId, Prorigo.Protrak.API.Contracts.Instance userProfile) {
var cacheKey = $"UserProfile:{userId}";
try {
// Await if cache write is important for correctness
await CacheService.SetAsync(cacheKey, userProfile, ttlSeconds: 3600);
} catch (Exception ex) {
// Log but don't fail the main flow
Logger.Warning(ex, "Cache set failed for {Key}", cacheKey);
}
}

// Fire and forget example for non-critical cache writes
public void CacheUserData(string key, object userData) {
// Not awaited: failure to cache is acceptable and lazy caching is fine
_ = CacheService.SetAsync(key, userData, ttlSeconds: 60);
}

Example: UpdateInstance / GetInstance

public async Task UpdateInstanceAsync(Guid instanceId, Prorigo.Protrak.API.Contracts.Instance instance) {
InstanceService.UpdateInstance(instance, instance.Modified);

// invalidate the cache
var cacheKey = $"Instance:{instanceId}";
await CacheService.RemoveAsync(cacheKey);
}

public async Task<Prorigo.Protrak.API.Contracts.Instance> GetInstanceAsync(Guid instanceId) {
var cacheKey = $"Instance:{instanceId}";
var cached = await CacheService.GetAsync<Prorigo.Protrak.API.Contracts.Instance>(cacheKey);
if (cached != null) return cached;

// Use InstanceService.GetInstance to load contract (synchronous as in API reference)
var instance = InstanceService.GetInstance(instanceId, new string[] { });
if (instance != null) {
await CacheService.SetAsync(cacheKey, instance, ttlSeconds: 3600);
return instance;
}
return null;
}

Guidance

  • Always await SetAsync when the cache must be updated before continuing. This ensures that any exceptions are caught and the cache is consistent.
  • Use fire-and-forget (_ = SetAsync(...)) only when cache write failure is not critical, such as for lazy caching scenarios where the next cache read is not immediate and you want caching to happen in the background while continuing with the next operation.
  • Consider logging exceptions from fire-and-forget cache writes to aid troubleshooting.

Troubleshooting

  • If values are not visible on reads, verify that both reader and writer use the same key format and serialization format.
  • If writes fail intermittently, inspect backend capacity, network reliability, and retry policies.