Contexte
J'essaie de mettre en œuvre un service Web API REST qui "enveloppe" un programme C existant.
Problème / Objectif
Étant donné que le programme C a un temps d'initialisation lent et une utilisation élevée de la RAM lorsque je lui demande d'ouvrir un dossier spécifique (je suppose que cela ne peut pas être amélioré), je pense mettre en cache le handle/objet C, de sorte que la prochaine fois qu'une requête GET atteint le même dossier, je peux utiliser le handle existant.
Ce que j'ai essayé
Déclarez tout d'abord un dictionnaire statique permettant de mettre en correspondance le chemin du dossier et la poignée :
static ConcurrentDictionary<string, IHandle> handles = new ConcurrentDictionary<string, IHandle>();
Dans ma fonction GET :
IHandle theHandle = handles.GetOrAdd(dir.Name, x => {
return new Handle(x); //this is the slow and memory-intensive function
});
De cette façon, chaque fois qu'un dossier spécifique a fait l'objet d'un GET auparavant, il aura déjà un identifiant prêt à être utilisé.
Pourquoi ce n'est pas bon
Je risque donc maintenant de manquer de mémoire si trop de dossiers sont mis en cache simultanément. Comment pourrais-je ajouter un processus d'arrière-plan de type GC pour TryRemove()
et appeler IHandle.Dispose()
sur les vieilles poignées, peut-être dans le cadre d'une politique du moins récemment utilisé ou du moins fréquemment utilisé ? Idéalement, il devrait commencer à se déclencher uniquement lorsque la mémoire physique disponible est faible.
J'ai essayé d'ajouter l'instruction suivante dans la fonction GET, mais cela semble trop compliqué et sa fonction est très limitée. Cette méthode ne fonctionne bien que si je veux que les poignées expirent toujours au bout de 10 secondes, et elle ne redémarre pas la minuterie si une nouvelle demande arrive dans les 10 secondes.
HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
System.Threading.Thread.Sleep(10000);
if (handles.TryRemove(dir.Name, out var handle2))
handle2.Dispose();
});
Ce que cette question n'est pas
Je ne pense pas que la mise en cache de la sortie soit la solution ici. Après avoir retourné le résultat de cette requête GET (il ne s'agit que des métadonnées du contenu du dossier), il se peut qu'il y ait une autre requête GET pour des données plus approfondies, ce qui nécessite l'appel à Handle
Les méthodes de l'UE.
J'espère que ma question est suffisamment claire !