Question

Je construis un modèle T4 qui va aider les gens à construire des files d'attente Azure d'une manière cohérente et simple. Je voudrais faire cette autodocumenté, et quelque peu cohérente.

  1. D'abord, je fait le nom de la file d'attente en haut du fichier, les noms de file d'attente doivent être en minuscules alors j'ai ajouté ToLower ()

  2. Le constructeur public utilise pour accéder aux chaînes de connexion de l'API StorageClient intégré. Je l'ai vu de nombreuses approches différentes à cela, et je voudrais obtenir quelque chose qui fonctionne dans presque toutes les situations. (Idées? Part faire)

  3. Je n'aime les requêtes HTTP non nécessaires pour vérifier si les files d'attente ont été créés alors j'ai fait un static bool. Je ne suis pas un verrou mettre en œuvre (monitorObject) puisque je ne pense pas que l'un est nécessaire.

  4. Au lieu d'utiliser une chaîne et l'analyse syntaxique avec des virgules (comme la plupart des documents MSDN) Je suis sérialisation l'objet lors du passage dans la file d'attente.

  5. Pour une optimisation plus loin, je suis sur un JSON sérialiseur méthode d'extension pour tirer le meilleur parti de la limite 8k. Je ne sais pas si un codage aidera à optimiser cette plus

  6. logique de nouvelle tentative d'ajout pour traiter certains scénarios qui se produisent avec la file d'attente (voir lien html)

  7. Q: est "DataContext" nom approprié pour cette classe

  8. Q: Est-ce une mauvaise pratique de nommer le nom d'action de file d'attente de la manière que je l'ai fait

Quels autres changements pensez-vous que je devrais faire?

public class AgentQueueDataContext
{
    // Queue names must always be in lowercase
    // Is named like a const, but isn't one because .ToLower won't compile...
    static string AGENT_QUEUE_ACTION_NAME = "AgentQueueActions".ToLower();

  static bool QueuesWereCreated { get; set; }

    DataModel.SecretDataSource secDataSource = null;

    CloudStorageAccount cloudStorageAccount = null;
    CloudQueueClient cloudQueueClient = null;
    CloudQueue queueAgentQueueActions = null;

    static AgentQueueDataContext()
    {
        QueuesWereCreated = false;
    }

    public AgentQueueDataContext() : this(false)
    {
    }
    public AgentQueueDataContext(bool CreateQueues)
    {
        // This pattern of setting up queues is from:
        // ttp://convective.wordpress.com/2009/11/15/queues-azure-storage-client-v1-0/
        //
        this.cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
        this.cloudQueueClient = cloudStorageAccount.CreateCloudQueueClient();
        this.secDataSource = new DataModel.SecretDataSource();

        queueAgentQueueActions = cloudQueueClient.GetQueueReference(AGENT_QUEUE_ACTION_NAME);

        if (QueuesWereCreated == false || CreateQueues)
        {
            queueAgentQueueActions.CreateIfNotExist();
            QueuesWereCreated = true;
        }
    }

  // This is the method that will be spawned using ThreadStart
   public void CheckQueue()
    {
        while (true)
        {
            try
            {
                CloudQueueMessage msg = queueAgentQueueActions.GetMessage();

                bool DoRetryDelayLogic = false;

                if (msg != null)
                {
                    // Deserialize using JSON (allows more data to be stored)
                    AgentQueueEntry actionableMessage = msg.AsString.FromJSONString<AgentQueueEntry>();

                    switch (actionableMessage.ActionType)
                    {
                        case AgentQueueActionEnum.EnrollNew:
                            {
                                // Add to 
                                break;
                            }
                        case AgentQueueActionEnum.LinkToSite:
                            {
                                // Link within Agent itself

                                // Link within Site

                                break;
                            }
                        case AgentQueueActionEnum.DisableKey:
                            {
                                // Disable key in site

                                // Disable key in AgentTable (update modification time)

                                break;
                            }
                        default:
                            {
                                break;
                            }
                    }

                    //
                    // Only delete the message if the requested agent has been missing for 
                    // at least 10 minutes
                    //
                    if (DoRetryDelayLogic)
                    {
                        if (msg.InsertionTime != null)
                            if (msg.InsertionTime < DateTime.UtcNow + new TimeSpan(0, 10, 10))
                                continue;

                        // ToDo: Log error: AgentID xxx has not been found in table for xxx minutes.   
                        //                  It is likely the result of a the registratoin host crashing.
                        //                  Data is still consistent.  Deleting queued message.
                    }


                    //
                    // If execution made it to this point, then we are either fully processed, or 
                    // there is sufficent reason to discard the message.
                    //
                    try
                    {
                        queueAgentQueueActions.DeleteMessage(msg);
                    }
                    catch (StorageClientException ex)
                    {
                        // As of July 2010, this is the best way to detect this class of exception
                        // Description: ttp://blog.smarx.com/posts/deleting-windows-azure-queue-messages-handling-exceptions
                        if (ex.ExtendedErrorInformation.ErrorCode == "MessageNotFound")
                        {
                            // pop receipt must be invalid
                            // ignore or log (so we can tune the visibility timeout)
                        }
                        else
                        {
                            // not the error we were expecting
                            throw;
                        }
                    }
                }
                else
                {
                   // allow control to fall to the bottom, where the sleep timer is...
                }
            }
            catch (Exception e)
            {
                // Justification: Thread must not fail.
                //Todo: Log this exception

                // allow control to fall to the bottom, where the sleep timer is...
                // Rationale: not doing so may cause queue thrashing on a specific corrupt entry
            }

            // todo: Thread.Sleep() is bad
            //       Replace with something better...
            Thread.Sleep(9000);
        }
Était-ce utile?

La solution

Q: Est-ce "DataContext" nom approprié pour cette classe

Dans .NET, nous avons beaucoup de classes DataContext, donc dans le sens que vous voulez que les noms de communiquer de façon appropriée ce que la classe le fait, je pense que XyzQueueDataContext communique correctement ce que la classe fait -., Bien que vous ne pouvez pas la requête de celui-ci

Si vous voulez rester plus aligné sur les langues motif accepté , Enterprise Integration Patterns - c'est ce que je ferais

Q: Est-ce une mauvaise pratique de nommer le nom d'action de file d'attente de la manière que je l'ai fait

?

Eh bien, il a certainement étroitement couples le nom de file d'attente à la classe. Cela signifie que si vous décidez que vous voulez découpler ceux-ci, vous ne pouvez pas.

D'une manière générale je pense que cette classe pourrait bénéficier d'essayer de faire moins. Utilisation de la file d'attente n'est pas la même chose que la gestion, donc au lieu d'avoir tous que le code de gestion de file d'attente là-bas, je vous suggère de injection CloudQueue dans l'instance. Voici comment je mets en œuvre mon constructeur AzureChannel:

private readonly CloudQueue queue;

public AzureChannel(CloudQueue queue)
{
    if (queue == null)
    {
        throw new ArgumentNullException("queue");
    }

    this.queue = queue;
}

correspond mieux unique Responsabilité Principe et vous pouvez maintenant mettre en œuvre dans sa propre file d'attente gestion classe (réutilisable).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top