Verwaltete Namespaces

Zusammenfassung

Einführung

Verwaltete Namespaces werden im Weave SDK verwendet, um Weave SDK-Entwicklern und Integratoren beworbene Anleitungen und Untertext zur Kennzeichnung bestimmter API-Sets im SDK zur Verfügung zu stellen. So können sie ihren Migrationspfad zwischen Weave SDK-Releases planen und vorhersagen und möglicherweise mehrere, gleichzeitige Weave APIs für ein bestimmtes Modul verwalten.

Bezeichnung

Verwaltete Namespaces können als eine von vier Bezeichnungen verwaltet werden:

Entwicklung

Jeder Namespace, der mit der Kennzeichnung „Development“ (Entwicklung) verwaltet wird, ist ein Hinweis für Entwickler und Integratoren, dass sich die darin enthaltenen APIs in der aktiven Entwicklung befinden, sich ändern können und nicht offiziell unterstützt werden. Von der Verwendung dieser APIs wird generell von Integratoren abgeraten, es sei denn, sie werden ausdrücklich dazu angewiesen.

Weiter

Jeder Namespace, der mit der Bezeichnung „Next“ verwaltet wird, ist ein Hinweis für Entwickler und Integratoren, dass die darin enthaltenen APIs zwar weitgehend aktive Entwicklung abgeschlossen haben, aber noch Änderungen unterliegen und für eine frühe Bewertung unterstützt werden. Die so vorgesehenen APIs stellen die nächste Entwicklungsstufe in einer Weave SDK-API dar und werden in unmittelbarer bis naher Zukunft in einem großen Freigabezyklus zu den aktuellen Standard-APIs.

Die Abwärtskompatibilität sowohl aus API- als auch aus Sicht des Over-the-Wire-Protokolls kann vorhanden sein, wird jedoch in so vorgesehenen APIs nicht garantiert.

Die Kennzeichnung des Next-verwalteten Namespace bietet Entwicklern und Integratoren einen Überblick darüber, wohin sich das Weave SDK bewegt. Dazu wird angegeben, was die aktuelle Standard-API in einem zukünftigen Release wird.

Die Bezeichnung „Nächster verwalteter Namespace“ ist optional, sodass ein verwalteter Namespace während eines Lebenszyklus übergehen kann, ohne ihn zu verwenden (siehe Lebenszyklus des verwalteten Namespace).

Aktuell

Jeder Namespace, der mit der aktuellen Kennzeichnung verwaltet wird, oder ein nicht verwalteter Namespace, d.h. ohne die Kennzeichnung eines verwalteten Namespace, stellt die aktuelle, standardmäßige, offiziell unterstützte API für diesen Teil oder das Modul des Weave SDK dar. Diese APIs werden zwar laufend verbessert, doch die Änderungen sind größtenteils die inkrementelle und Abwärtskompatibilität, sowohl für die API als auch für Over-the-Wire.

Die Kennzeichnung „Aktueller verwalteter Namespace“ ist optional, sodass ein verwalteter Namespace während eines Lebenszyklus übergehen kann, ohne ihn zu verwenden (siehe Lebenszyklus des verwalteten Namespace). Tatsächlich ist jeder nicht verwaltete Namespace implizit aktuell.

Legacy

Jeder Namespace, der mit der Legacy-Kennzeichnung verwaltet wird, weist Entwickler und Integratoren darauf hin, dass die darin enthaltenen APIs veraltet sind und durch eine neue, aktuelle API ersetzt werden. Diese APIs stellen die frühere API dar.

Die entsprechenden APIs werden mit der nächsten Weave SDK-Hauptversion eingestellt. Daher sollten Entwickler und Integratoren Pläne für die Migration weg von diesen APIs aufstellen, wenn sie bei den führenden Weave SDK-Releases bleiben möchten.

Lebenszyklus des verwalteten Namespace

Die folgende Abbildung zeigt den Lebenszyklus eines verwalteten Namespace beim Übergang vom Entwicklungs- und möglicherweise zum Legacy-Namespace:

.-------------.      .- - - .      .- - - - -.      .--------.
| Development | -.->   Next   -.->   Current   ---> | Legacy |
'-------------'  |   '- - - '  |   ' - - - - '      '--------'
                 |             |
                 '-------------'

Wenn es verwendet wird, beginnt der Lebenszyklus des verwalteten Namespace mit der Bezeichnung Development.

Wenn die Entwicklung abgeschlossen ist und der Code zur Evaluierung und Integration bereit ist, wird die Kennzeichnung entweder zu „Weiter“ oder „Aktuell“ migriert. Alternativ kann die Kennzeichnung ganz wegfallen und der verwaltete Namespace nicht mehr verwendet wird. Dadurch wird die Kennzeichnung praktisch implizit als "Current" (Aktuell) übernommen.

Wenn der Code zusammenleben soll und den aktuellen Code noch nicht ersetzt, sollte die Kennzeichnung zu „Weiter“ migriert werden. Wenn der Code den aktuellen Code ersetzen soll, sollte die Kennzeichnung zu „Current“ migriert werden.

Bei Verwendung der Kennzeichnung „Next“ (Weiter) wird die Kennzeichnung zu „Current“ (Aktuell) migriert, nachdem der Code die gewünschte Anzahl von Release- und Bewertungszyklen durchlaufen hat. Unter Umständen wird die Kennzeichnung auch ganz entfernt.

Wenn der Code unter Verwendung der aktuellen Kennzeichnung durch neuen Code ersetzt werden soll, aber noch eine Reihe von Releasezyklen gewartet werden muss, wird die Kennzeichnung zu „Legacy“ migriert.

Aus der Legacy-Kennzeichnung wird der Code schließlich ganz aus dem Weave SDK entfernt.

Verwaltete Namespaces verwenden

Weave SDK-Nutzer können mit verwalteten Namespaces entweder als Entwickler interagieren, indem sie vorhandenen Code erweitern und verwalten, oder als Integrator, der Weave in ihre eigene Anwendung, Plattform und ihren Systemcode integriert. In den folgenden beiden Abschnitten finden Sie Empfehlungen zum Umgang mit von Weave verwalteten Namespaces aus diesen beiden Perspektiven.

Verwaltete Namespaces als Entwickler verwenden

Ein Hauptschwerpunkt des Weave SDK-Entwicklers ist die Verbesserung und Entwicklung neuer Weave SDK-APIs und -Funktionen, während in vielen Fällen gleichzeitig vorhandene API- und Funktionsbereitstellungen unterstützt werden.

Wenn es nicht möglich ist, beide Schwerpunkte auf abwärtskompatible Weise innerhalb derselben API zu erfüllen, bieten verwaltete Namespaces einen Mechanismus, um diese APIs parallel zu verwalten, ohne vorhandene API- und Funktionsbereitstellungen zu beeinträchtigen.

Nehmen wir als Arbeitsbeispiel an, dass das Weave-Profil Mercury derzeit in der folgenden, nicht verwalteten Namespace-Hierarchie vorhanden ist:

namespace nl {
namespace Weave {
namespace Profiles {
namespace Mercury {

// ...

}; // namespace Mercury
}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

und die folgenden öffentlichen Header:

  • Weave/Profiles/Mercury/Mercury.hpp
  • Weave/Profiles/Mercury/Bar.hpp
  • Weave/Profiles/Mercury/Foo.hpp
  • Weave/Profiles/Mercury/Foobar.hpp

wobei Mercury.hpp der Header des Moduls "umbrella" ist. Die meisten Integratoren fügen einfach den Header des Moduls „umbrella“ ein, wie hier gezeigt:

#include 

Die Entwicklung von Mercury hat jedoch einen Punkt erreicht, an dem eine nächste Generation der APIs und möglicherweise des Over-the-Wire-Protokolls entwickelt werden muss, die mit bestehenden Bereitstellungen nicht abwärtskompatibel sind. Mit verwalteten Namespaces kann dies erreicht werden, ohne dass diese vorhandenen Bereitstellungen beeinträchtigt werden.

Vorhandenen Namespace auf aktuellen Namespace verschieben

Da wir den aktuellen Release der API und die entsprechenden Funktionen für vorhandene bereitgestellte Integrationen weiterhin unterstützen möchten, besteht die erste Aufgabe darin, den aktuellen Code zu verschieben:

% cd src/lib/profiles/mercury
% mkdir Current
% mv Mercury.hpp Bar.hpp Foo.hpp Foobar.hpp *.cpp Current/

Hinweis: Zusätzlich zum Verschieben der Dateien sollte auch die Kopfzeile mit Schutzmaßnahmen für die verschobenen Dateien umbenannt werden und sie möglicherweise mit „_CURRENT“ versehen, da neue, ähnlich benannte Dateien an ihrem Ort unten erstellt werden.

Nachdem der Code verschoben wurde, besteht der nächste Schritt darin, den Namespace mit der entsprechenden Bezeichnung, hier „Current“, zu verwalten. Erstellen Sie zuerst einen Header, der den verwalteten Namespace definiert, und zwar "Current/MercuryManagedNamespace.hpp". Es ist besser, einen solchen Header zu erstellen, als diesen Inhalt in jeder Header-Datei zu wiederholen und zu duplizieren, wenn mehrere Header-Dateien vorhanden sind.

% cat << EOF > Current/MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP

#include 

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE) && WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Current
#error Compiling Weave Mercury current-designation managed namespace file with WEAVE_CONFIG_MERCURY_NAMESPACE defined != kWeaveManagedNamespace_Current
#endif

#ifndef WEAVE_CONFIG_MERCURY_NAMESPACE
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current
#endif

namespace nl {
namespace Weave {
namespace Profiles {

namespace WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Current) { };

namespace Mercury = WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Current);

}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP
EOF

Als Nächstes fügen Sie diesen Header vor anderen modulspezifischen Einschlussanweisungen in die vorhandenen Header ein. Beispiel:

#include 

#include 

Kompatibilitätsheader erstellen

Das Verschieben der vorhandenen Header an einen neuen Speicherort und die Verwaltung ihres Namespace allein reicht jedoch nicht aus, um sicherzustellen, dass vorhandene Bereitstellungen ohne Änderungen funktionieren, da sie alle Include-Anweisungen verwenden, die die zuvor verschobenen Header angegeben haben.

Um dieses Problem zu beheben, müssen Kompatibilitäts-Wrapper-Header mit Namen erstellt werden, die den gerade verschobenen Namen entsprechen.

% touch Mercury.hpp Bar.hpp Foo.hpp Foobar.hpp

Wenn nur ein aktuell festgelegter verwalteter Namespace erstellt wird, ohne dafür einen vom „Development“ oder „Next“ festgelegten verwalteten Namespace zu erstellen, kann der Inhalt dieser Dateien einfach aus einem Header-Include-Guard und einer Include-Anweisung bestehen, die den neu verschobenen Header mit demselben Namen angibt:

#ifndef _WEAVE_MERCURY_BAR_HPP
#define _WEAVE_MERCURY_BAR_HPP

#include 

#endif // _WEAVE_MERCURY_BAR_HPP

Wenn jedoch auch ein „Development“ oder „Next“ verwalteter Namespace erstellt wird, um eine neue, inkompatible Entwicklung zu ermöglichen, ist eine etwas komplexere Vorgehensweise erforderlich.

Wie zuvor wird ein Header für die Konfiguration des verwalteten Namespace erstellt, hier als MercuryManagedNamespace.hpp. Dies ist wiederum besser als das Wiederholen und Duplizieren dieses Inhalts in jeder Header-Datei, wenn mehrere Header-Dateien vorhanden sind.

% cat << EOF > MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP

#include 

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE)                             \
  && (WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Current) \
  && (WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Development)
#error "WEAVE_CONFIG_MERCURY_NAMESPACE defined, but not as namespace kWeaveManagedNamespace_Current or kWeaveManagedNamespace_Development"
#endif

#if !defined(WEAVE_CONFIG_MERCURY_NAMESPACE)
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current
#endif

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP
EOF

Beachten Sie, dass dies wie gewünscht standardmäßig die Bezeichnung des verwalteten Namespace auf „Aktuell“ gesetzt wird, wenn keine Konfiguration definiert wurde.

Mit diesem Header können die Header des Kompatibilitäts-Wrappers nun so bearbeitet werden, dass sie Folgendes enthalten:

#include 

#if WEAVE_CONFIG_MERCURY_NAMESPACE == kWeaveManagedNamespace_Development
#include 
#else
#include 
#endif // WEAVE_CONFIG_MERCURY_NAMESPACE == kWeaveManagedNamespace_Development

oder was für den jeweiligen Anwendungsfall der Namespace-Verwaltung geeignet ist.

Entwicklungsinhalte erstellen

Die Infrastruktur ist nun so eingerichtet, dass neben den vorhandenen Funktionen und APIs neue Funktionen und APIs erstellt werden können.

% mkdir Development
% touch Development/Mercury.hpp Development/Bar.hpp Development/Foo.hpp Development/Foobar.hpp
% cat << EOF > Development/MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP

#include 

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE) && WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Development
#error Compiling Weave Mercury development-designated managed namespace file with WEAVE_CONFIG_MERCURY_NAMESPACE defined != kWeaveManagedNamespace_Development
#endif

#ifndef WEAVE_CONFIG_MERCURY_NAMESPACE
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Development
#endif

namespace nl {
namespace Weave {
namespace Profiles {

namespace WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Development) { };

namespace Mercury = WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Development);

}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP
EOF

Wenn ein Modul wesentlich einfacher ist als das hier dargestellte Beispiel und nicht viele Klassen, Quellen, Dateien oder Header hat, kann dies natürlich in derselben Headerdatei erreicht werden, ohne Dateien zu verschieben und mehrere eigenständige Konfigurations- und Kompatibilitätsheader zu erstellen. Bei diesem komplexen Beispiel sollte es jedoch zu Lösungen für verwaltete Namespaceen führen, die von komplex bis einfach reichen.

Verwaltete Namespaces als Integrator verwenden

Ein Schwerpunkt des Weave SDK-Integrators ist die Einbindung der entsprechenden öffentlichen API-Header des Weave SDK sowie die Integration und Entwicklung von Anwendungen dafür.

Nehmen wir als Beispiel wieder das Weave-Profil Mercury mit den als Next-, Current- und Legacy-spezifischen verwalteten Namespaces an, deren öffentliche Header wie folgt strukturiert sind:

  • Weave/Profiles/Mercury/Mercury.hpp
  • Weave/Profiles/Mercury/Bar.hpp
  • Weave/Profiles/Mercury/Foo.hpp
  • Weave/Profiles/Mercury/Foobar.hpp
  • Weave/Profiles/Mercury/Next/Mercury.hpp
  • Weave/Profiles/Mercury/Next/Bar.hpp
  • Weave/Profiles/Mercury/Next/Foo.hpp
  • Weave/Profiles/Mercury/Next/Foobar.hpp
  • Weave/Profiles/Mercury/Current/Mercury.hpp
  • Weave/Profiles/Mercury/Current/Bar.hpp
  • Weave/Profiles/Mercury/Current/Foo.hpp
  • Weave/Profiles/Mercury/Current/Foobar.hpp
  • Weave/Profiles/Mercury/Legacy/Mercury.hpp
  • Weave/Profiles/Mercury/Legacy/Bar.hpp
  • Weave/Profiles/Mercury/Legacy/Foo.hpp
  • Weave/Profiles/Mercury/Legacy/Foobar.hpp

wobei Mercury.hpp der Header des Moduls "umbrella" ist.

Es sei denn, der vorliegende Anwendungsfall motiviert dazu, ein durch einen Namespace verwaltetes Modul in Weave explizit einzubeziehen. Beispiel:

#include 

Am besten verweisen Sie auf öffentliche Weave-Modul-Header anhand ihrer nicht verwalteten Standardpfade (z.B. Weave/Profiles/Mercury/Mercury.hpp). So können Sie die API-Entwicklung verfolgen, ohne die Include-Anweisungen eines Projekts kontinuierlich zu ändern, während diese APIs den verwalteten lifecycle durchlaufen.

Gemäß dieser Strategie können Bereitstellungen dann ihren Code auf eine andere verwaltete Namespace-Bezeichnung, z. B. die aktuelle Bezeichnung, neu ausrichten, indem die gewünschte Konfiguration im C/C++-Präprozessor angegeben wird. Dies kann in der Befehlszeile, im Quellcode oder in einem Konfigurations- oder Präfix-Header erfolgen:

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current

und verwenden Sie den nicht verwalteten / unqualifizierten Include-Pfad:

#include 

Wenn sich die Kennzeichnung des verwalteten Namespace für die Ziel-APIs ändert (z. B. von „Aktuell“ zu „Alt“), können Sie einfach ein Retargeting durchführen, indem Sie die Präprozessordefinition anpassen:

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Legacy