Frage

Ich erstelle eine T4 -Vorlage, die Menschen hilft, Azure -Warteschlangen konsistent und einfach zu konstruieren. Ich möchte dieses Selbstdokumentieren und etwas konsistent machen.

  1. Zuerst habe ich den Warteschlangennamen oben in der Datei gemacht. Die Warteschlangennamen müssen in Kleinbuchstaben sein, also habe ich Tolower hinzugefügt ()

  2. Der öffentliche Konstruktor verwendet die integrierten APIs in StorageClients, um auf die Verbindungszeichenfolgen zuzugreifen. Ich habe viele verschiedene Ansätze dafür gesehen und möchte etwas bekommen, das in fast allen Situationen funktioniert. (Ideen? Teilen)

  3. Ich mag die nicht benötigten HTTP -Anfragen, um zu überprüfen, ob die Warteschlangen erstellt wurden, so static bool . Ich habe kein Schloss (MonitorObject) implementiert, da ich nicht denke, dass einer benötigt wird.

  4. Anstatt eine Zeichenfolge zu verwenden und sie mit Kommas zu analysieren (wie die meisten MSDN -Dokumentation), serialisiere ich das Objekt beim Übergeben in die Warteschlange.

  5. Zur weiteren Optimierung verwende ich a JSON Serializer -Erweiterungsmethode Um das Beste aus der 8K -Grenze herauszuholen. Ich bin mir nicht sicher, ob eine Codierung dazu beiträgt, dies zu optimieren

  6. Wiederholungslogik hinzugefügt, um bestimmte Szenarien zu verarbeiten, die mit der Warteschlange auftreten (siehe HTML -Link)

  7. Q: Ist "DataContext" für diese Klasse geeigneter Name?

  8. Q: Ist es eine schlechte Praxis, den Warteschlange -Aktionsnamen so zu nennen, wie ich es getan habe?

Welche zusätzlichen Änderungen sollte ich Ihrer Meinung nach vornehmen?

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);
        }
War es hilfreich?

Lösung

F: Ist "DataContext" für diese Klasse geeigneter Name?

In .NET haben wir viele DataContext -Klassen XyzQueueDataContext Kommuniziert ordnungsgemäß, was die Klasse tut - obwohl Sie nicht davon abfragen können.

Wenn Sie mehr anpassen möchten Akzeptierte Mustersprachen, Muster der Enterprise -Anwendungsarchitektur Ruft jede Klasse auf, die den Zugriff auf ein externes System für a zusammenfasst Tor, zwar genauer gesagt, Sie möchten den Begriff möglicherweise verwenden Kanal in der Sprache von Unternehmensintegrationsmuster - Das würde ich tun.

F: Ist es eine schlechte Praxis, den Namen der Warteschlangenaktionen so zu nennen, wie ich es getan habe?

Nun, es ist sicherlich dicht Paare Der Warteschlangenname zur Klasse. Dies bedeutet, dass Sie dies nicht können, wenn Sie später entscheiden, dass Sie diese entscheiden möchten.

Als allgemeiner Kommentar denke ich, dass diese Klasse davon profitieren könnte, weniger zu tun. Die Verwendung der Warteschlange ist nicht dasselbe wie das Verwalten injizieren ein Wolkenqueue in die Instanz. So implementiere ich meinen Azurechannel -Konstruktor:

private readonly CloudQueue queue;

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

    this.queue = queue;
}

Dies passt besser zum Einzelverantwortungsprinzip Und Sie können jetzt das Warteschlangenmanagement in seiner eigenen (wiederverwendbaren) Klasse implementieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top