2013-08-03 4 views
0

Comment créer une file d'attente différée sur disque dans Go?Array de disques dans Go

J'écris un programme Go pour effectuer certaines actions sur les données après certains intervalles de temps. Voici une version dépouillée.

func IncomingJob (data MyStruct) { 
    //Run immediately 
    dosomething(&data, 1) 
    time.Sleep(5 * time.Minute) 
    //Run after 5 minutes has passed from initial arrival 
    dosomething(&data, 2) 
    time.Sleep(5 * time.Minute) 
    //Run after 10 minutes has passed from initial arrival 
    dosomething(&data, 3) 
    time.Sleep(50 * time.Minute) 
    //Run after 60 minutes has passed from initial arrival 
    dosomething(&data, 4) 
} 

Cette fonction serait initialisée en tant que goroutinue.

go IncomingJob(data) 

Le problème que j'ai est que chaque instance de IncomingJob dure 60 minutes et l'objet MyStruct reste en mémoire pour cette durée. L'utilisation totale de la mémoire est assez énorme. Si je veux supporter 1 million d'exécutions par heure, cela signifie qu'à tout moment, il y a 1 million d'objets en attente de mémoire qui ne font rien, MyStruct. Je peux aussi utiliser time.AfterFunc pour cela, mais cela ne change rien à l'utilisation de la mémoire.

Existe-t-il une implémentation de file d'attente/tampon FIFO sauvegardée sur disque dans Go? De cette façon, je pourrais avoir 3 files d'attente (pour différents intervalles) et l'interroger et dormir jusqu'à son heure correcte pour les données interrogées à retraiter. De cette façon, je perdrais certains cycles de CPU en sérialisation, ajouterais une latence d'E/S à une application autrement en mémoire mais économiserais énormément de mémoire.

Mise à jour: time.AfterFunc utilise beaucoup moins de mémoire.

func IncomingJob (data MyStruct) { 
    //Run immediately 
    dosomething(&data, 1) 
    time.AfterFunc(5 * time.Minute, func() { 
     //Run after 5 minutes has passed from initial arrival 
     dosomething(&data, 2) 
     time.AfterFunc(5 * time.Minute, func() { 
      //Run after 10 minutes has passed from initial arrival 
      dosomething(&data, 3) 
     }) 
      time.AfterFunc(50 * time.Minute, func() { 
       //Run after 50 minutes has passed from initial arrival 
       dosomething(&data, 4) 
     }) 
    }) 
} 

Répondre

0

Cela ressemble à un travail pour un embedded database. Je suis sûr qu'un FIFO peut être modélisé assez facilement par exemple. un magasin de clés/valeurs NoSQL.

Vous voudrez peut-être jeter un oeil à kv (auteur ici). Catch: les valeurs sont limitées à 64 Ko, vous devrez donc composer des éléments FIFO séparés sur plus d'une paire K/V.

+0

http://godoc.org/github.com/cznic/kv#DB.First - Comment est sélectionné le premier? Est-ce le plus tôt entré k, v qui existe encore dans la DB? btw votre kv semble parfait pour une autre partie du code devrais-je besoin d'ajouter de la durabilité dans l'application. – sajal

+0

@sajal: Première: dans l'ordre d'assemblage des clés. Donc oui, si vous utilisez une séquence de nombres ordonnée (ou time.Now(). UnixNano()) comme clés, alors .First renverra l'élément "le plus ancien" encore dans la base de données. – zzzz