Domanda

Sto costruendo un modello T4 che aiuterà le persone costruiscono le code Azure in modo coerente e semplice. Mi piacerebbe fare questa auto-documentazione, e un po 'coerente.

  1. Per prima cosa ho fatto il nome della coda nella parte superiore del file, i nomi delle code devono essere in minuscolo così ho aggiunto ToLower ()

  2. Il costruttore pubblico utilizza il built-in StorageClient API per accedere alle stringhe di connessione. Ho visto molti approcci diversi a questo, e vorrei ottenere qualcosa che funziona in quasi tutte le situazioni. (Idee? Fare la parte)

  3. mi piace il richieste HTTP non necessari per verificare se sono state create le code così ho fatto è un static bool. Non ho implementare un blocco (monitorObject) in quanto non credo che uno è necessario.

  4. Invece di usare una stringa e l'analisi con le virgole (come la maggior parte della documentazione MSDN) Sto serializzazione l'oggetto quando si passa in coda.

  5. Per ottimizzare ulteriormente sto usando un JSON serializzatore metodo di estensione per ottenere il massimo del limite 8k. Non sono sicuro se una codifica contribuirà a ottimizzare questo più

  6. logica aggiunta di tentativi per gestire alcuni scenari che si verificano con la coda (vedi link html)

  7. D: è "DataContext" nome appropriato per questa classe

  8. D: E 'una pratica povero di nominare il Nome coda d'azione nel modo che ho fatto

Quali ulteriori modifiche pensi che dovrei fare?

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);
        }
È stato utile?

Soluzione

D: È "DataContext" nome appropriato per questa classe

In .NET abbiamo un sacco di classi DataContext, quindi, nel senso che si vuole nomi di comunicare in modo appropriato ciò che la classe fa, penso XyzQueueDataContext comunica correttamente ciò che la classe fa -. Anche se non è possibile interrogare da esso

Se si vuole rimanere più allineati alle lingue modello accettato , modelli di Enterprise Application Architecture invita qualsiasi classe che incapsula l'accesso a un sistema esterno per un Gateway , mentre più in particolare si consiglia di usare il termine canale nella lingua di Enterprise Integration - questo è quello che avrei fatto

D: E 'una pratica povero di nominare il Nome coda d'azione nel modo che ho fatto

?

Beh, è ??certamente strettamente coppie il nome della coda alla classe. Ciò significa che se in seguito si decide che si desidera disaccoppiare quelli, non è possibile.

In linea generale credo che questa classe potrebbe trarre beneficio da cercando di fare meno. Utilizzando la coda non è la stessa cosa di gestione, così invece di avere tutto quel codice gestione delle code lì, io suggerirei di iniezione un CloudQueue nell'istanza. Ecco come ho implementare il mio costruttore AzureChannel:

private readonly CloudQueue queue;

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

    this.queue = queue;
}

Questa è adatto ai migliori singolo Responsabilità Principio e ora è possibile implementare coda di gestione in proprio (riutilizzabile) di classe.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top