Concepts
Cette rubrique explique certains des concepts clés relatifs à l'utilisation de la trousse SDK pour TypeScript et JavaScript.
Cette rubrique explique certains des concepts clés relatifs à l'utilisation de la trousse SDK pour TypeScript et JavaScript.
Demandes brutes
Les demandes brutes sont utiles et, dans certains cas, nécessaires. Cas d'utilisation courants : Lors de l'utilisation de votre propre client HTTP, qui soumet une demande OCI authentifiée à un autre point d'extrémité, et qui soumet une demande à une API OCI qui n'est pas prise en charge actuellement dans la trousse SDK. La trousse SDK pour TypeScript et JavaScript présente la classe DefaultRequestSigner que vous pouvez utiliser pour créer une instance et appeler signHttpRequest.
L'exemple de demande brute sur GitHub montre comment créer une instance de DefaultRequestSigner et appeler signHttpRequest.
Chargement d'objets volumineux
Le service de stockage d'objets prend en charge les chargements en plusieurs parties pour faciliter les chargements d'objets volumineux en fractionnant l'objet volumineux en parties. La trousse SDK pour TypeScript et JavaScript prend en charge une classe de chargement de niveau supérieur utilisant les API de chargement en plusieurs parties. La rubrique Gestion des chargements en plusieurs parties fournit des liens aux API utilisées pour les opérations de chargement en plusieurs parties. Les chargements en plusieurs parties de niveau supérieur sont mis en oeuvre à l'aide d'UploadManager qui fractionne un objet volumineux en plusieurs parties pour vous, charge les parties en parallèle, puis recombine et valide les parties en un seul objet dans le stockage. L'exemple UploadObject montre comment utiliser UploadManager pour fractionner automatiquement un objet en plusieurs parties afin de simplifier les interactions avec le service de stockage d'objets.
Nouvelles tentatives
Les nouvelles tentatives pour les opérations à corps binaire ou de type flux (par exemple putObject ou uploadPart) ne sont effectuées que si la propriété
backupBinaryBody
est réglée à true
dans la configuration des nouvelles tentatives par défaut, ou si vous ne fournissez pas la longueur du contenu dans la demande.Par défaut, la trousse SDK retente les opérations avec les codes de statut de réponse HTTP 409 (avec un code d'erreur IncorrectState), 429, 500, 502, 503, 504, les erreurs de temporisation (temporisations de connexion HTTP et de lecture, par exemple), les erreurs de connexion de demande, les exceptions de demande et les exceptions de disjoncteur.
La configuration par défaut la plus courante et la liste des erreurs qui peuvent faire l'objet de nouvelles tentatives sont visibles sur Github.
Désactivation des nouvelles tentatives par défaut
- Réglez la variable d'environnement
OCI_SDK_DEFAULT_RETRY_ENABLED
àfalse
pour désactiver les nouvelles tentatives par défaut globalement. - Remplacez la configuration globale des nouvelles tentatives par défaut :
let retryConfiguration : common.RetryConfiguration = { terminationStrategy : new common.MaxAttemptsTerminationStrategy(1) }; common.GenericRetrier.defaultRetryConfiguration = retryConfiguration;
- Remplacez les nouvelles tentatives par défaut pour une instance client spécifique. Cet exemple montre comment remplacer les nouvelles tentatives par défaut pour
objectStorageClient
:const provider: common.ConfigFileAuthenticationDetailsProvider = new common.ConfigFileAuthenticationDetailsProvider(); const client = new objectstorage.ObjectStorageClient({authenticationDetailsProvider : provider}, { retryConfiguration : { terminationStrategy : new common.MaxAttemptsTerminationStrategy(1) } });
- Remplacez les nouvelles tentatives par défaut pour une instance de demande spécifique. Cet exemple illustre le remplacement des nouvelles tentatives pour
putObjectRequest
:const putObjectRequest : objectstorage.requests.PutObjectRequest = { objectName : objectName, bucketName : bucketName, namespaceName : namespaceName, putObjectBody : stream, retryConfiguration : { terminationStrategy : new common.MaxAttemptsTerminationStrategy(1) } }
Priorité du comportement des nouvelles tentatives
- Toute configuration définie explicitement au niveau de la demande remplace la configuration au niveau du client ou la configuration globale par défaut et la configuration au moyen de la variable d'environnement, pour cette demande spécifique.
- Toute configuration définie explicitement au niveau du client remplace la configuration globale par défaut et la configuration au moyen de la variable d'environnement, pour ce client particulier.
- La configuration par défaut définie au niveau global par programmation a priorité sur le remplacement au niveau de la variable d'environnement.
Stratégies de traitement des nouvelles tentatives
Vous pouvez spécifier la stratégie à utiliser pour le traitement des nouvelles tentatives, notamment le nombre de nouvelles tentatives, la condition selon laquelle la trousse SDK doit retenter une opération et le moment auquel arrêter les nouvelles tentatives. Vous pouvez définir ces paramètres au niveau du client et au niveau de la demande individuelle.
Stratégie de délai
Le paramètre delayStrategy
détermine la durée d'attente entre chaque appel de nouvelle tentative. Deux options sont disponibles pour ce paramètre :
FixedTimeDelayStrategy (seconds)
- Le délai avant chaque nouvelle tentative est spécifié en nombre de secondes.ExponentialBackoffStrategy (seconds)
- Le délai pour les appels suivants de nouvelle tentative est augmenté selon un facteur exponentiel de 2 jusqu'à ce qu'il atteigne le délai maximal défini (en secondes), avec une valeur de base d'une seconde.
La stratégie de délai par défaut est réglée à ExponentialBackoffDelayStrategy
avec une valeur de gigue comprise entre 0 et 1 000 millisecondes et un temps d'attente maximal entre les appels de 30 secondes.
Condition de nouvelle tentative
retryCondition
définit une fonction avec un argument d'erreur qui retourne un booléen indiquant s'il faut réessayer ou non. L'opération sera retentée si cette fonction retourne true
.Pour toutes les demandes à corps binaire ou de type flux, les nouvelles tentatives ne sont effectuées que si
RetryConfiguration.backupBinaryBody
est réglé à true
ou si le corps de type flux initial peut faire l'objet d'une nouvelle tentative. Par défaut, les corps de type flux ne sont pas sauvegardés. Les corps de type flux ne sont sauvegardés que si backupBinaryBody
est réglé à true
ou si vous ne fournissez pas la longueur du contenu dans la demande.Stratégie d'arrêt
Le paramètre terminationStrategy
définit quand mettre fin aux nouvelles tentatives. Ce paramètre prend en charge les options suivantes :
MaxTimeTerminationStrategy (seconds)
- Définit la durée totale en secondes pour la nouvelle tentative.MaxAttemptsTerminationStrategy (attempts)
- Définit le nombre total de nouvelles tentatives.
La stratégie d'interruption par défaut pour les trousses SDK pour OCI est une valeur MaxAttemptsTerminationStrategy
réglée à 8
.
Exemples de nouvelles tentatives
TypeScript
Cet exemple définit la configuration des nouvelles tentatives au niveau du client :
const provider: common.ConfigFileAuthenticationDetailsProvider = new common.ConfigFileAuthenticationDetailsProvider();
const client = new objectstorage.ObjectStorageClient({authenticationDetailsProvider : provider}, {
retryConfiguration : {
delayStrategy : new common.FixedTimeDelayStrategy(5),
terminationStrategy : new common.MaxTimeTerminationStrategy(30),
retryCondition : (error) => { return error.statusCode >= 500;
}
}
const request: identity.requests.ListAvailabilityDomainsRequest = {
compartmentId: tenancyId,
retryConfiguration : {
terminationStrategy : new common.MaxAttemptsTerminationStrategy(6),
}
};
let retryConfiguration : common.RetryConfiguration = {
terminationStrategy : new common.MaxAttemptsTerminationStrategy(1)
};
common.GenericRetrier.defaultRetryConfiguration = retryConfiguration;
JavaScript
Cet exemple définit la configuration des nouvelles tentatives au niveau du client :
const provider: common.ConfigFileAuthenticationDetailsProvider = new common.ConfigFileAuthenticationDetailsProvider();
const client = new objectstorage.ObjectStorageClient({authenticationDetailsProvider : provider}, {
retryConfiguration : {
delayStrategy : new common.FixedTimeDelayStrategy(5),
terminationStrategy : new common.MaxTimeTerminationStrategy(30),
retryCondition : (error) => { return error.statusCode >= 500;
}
}
Cet exemple définit la configuration des nouvelles tentatives au niveau de la demande :
const request = {
compartmentId: tenancyId,
retryConfiguration : {
terminationStrategy : new common.MaxAttemptsTerminationStrategy(6),
}
};
let retryConfiguration = {
terminationStrategy : new common.MaxAttemptsTerminationStrategy(1)
};
common.GenericRetrier.defaultRetryConfiguration = retryConfiguration;
Scrutation avec des processus en attente
La trousse SDK pour TypeScript offre des processus en attente qui permettent à votre code d'attendre qu'une ressource spécifique atteigne l'état souhaité. Un processus en attente attend que l'état souhaité soit atteint ou qu'une temporisation soit dépassée. Les processus en attente convertissent la logique de scrutation (que vous auriez à écrire autrement) en un appel de méthode unique facile à utiliser.
Les processus en attente sont obtenus au moyen du client du service client.createWaiter()
. Les processus en attente utilisent un objet de configuration facultatif pour permettre aux utilisateurs de contrôler la durée d'attente et la durée entre les tentatives de scrutation. L'exemple suivant montre comment créer un processus en attente avec la configuration facultative :
// The waiter configuration used when creating our waiters. import common = require("oci-common"); import identity = require("oci-identity"); const maxTimeInSeconds = 60 * 60; // The duration for waiter configuration before failing. Currently set to 1 hour. const maxDelayInSeconds = 30; // The max delay for the waiter configuration. Currently set to 30 seconds const waiterConfiguration: common.WaiterConfiguration = { terminationStrategy: new common.MaxTimeTerminationStrategy(maxTimeInSeconds), delayStrategy: new common.ExponentialBackoffDelayStrategy(maxDelayInSeconds) }; const identityClient = new identity.identityClient({ authenticationDetailsProvider: provider }); const identityWaiter = identityClient.createWaiters(waiterConfiguration);
Disjoncteurs
À partir de la version 2.8.0, la trousse SDK pour Typescript et Javascript prend en charge les disjoncteurs par défaut. Les disjoncteurs permettent d'éviter que le client submerge le service en bloquant l'envoi des demandes à celui-ci après qu'un certain seuil d'échec a été atteint. Pour les disjoncteurs par défaut, toutes les erreurs pour lesquelles une nouvelle tentative est possible sont traitées comme des défaillances.
Les paramètres suivants définissent un disjoncteur :
- Seuil de taux d'échec - L'état du disjoncteur passe de CLOSED à OPEN lorsque le taux d'échec est égal ou supérieur à ce seuil. Par exemple, lorsque plus de 50 % des appels enregistrés ont échoué, le disjoncteur s'ouvre.
- Temporisation de réinitialisation - Délai après lequel un disjoncteur ouvert tente d'exécuter une demande.
- Exceptions d'échec - Liste des exceptions qui sont considérées comme des échecs pour le disjoncteur.
- Seuil de nombre minimal d'appels/volume - Nombre minimal d'appels requis (par période de fenêtre glissante) avant que le disjoncteur puisse calculer le taux d'erreur.
Configuration des coupe-circuits par défaut
La configuration des disjoncteurs par défaut est la suivante :
- Seuil de taux d'échec : 80 %. Lorsque 80 % des demandes calculées pour une période de 120 secondes ont échoué, le disjoncteur fermé s'ouvre.
- Seuil de nombre minimum d'appels/volume : 10, pour la période de 120 secondes définie ci-dessus.
- T délai d'attente de réinitialisation : le interrupteur attend 30 secondes avant de régler l'interrupteur à l'état
halfOpen
et de retenter l'action. - Anomalies d'échec : Les défaillances du circuit sont seulement enregistrées pour les exceptions réexécutables ou transitoires. Les codes de réponse HTTP 409 (avec IncorrectState), 429, 500, 502, 503 et 504, les temporisations de demande HTTP et autres, les erreurs et exceptions de connexion de demande sont considérés comme des défaillances qui déclenchent un disjoncteur.
Désactivation du disjoncteur par défaut
Pour désactiver la fonction de disjoncteur par défaut, vous pouvez effectuer l'une des opérations suivantes :
- Réglez la variable d'environnement
OCI_SDK_DEFAULT_CIRCUITBREAKER_ENABLED
àfalse
pour désactiver les disjoncteurs par défaut globalement. - Désactivez les disjoncteurs par défaut globaux par programmation :
common.CircuitBreaker.EnableGlobalCircuitBreaker = false
- Remplacez la configuration globale des disjoncteurs par défaut :
let customDefaultCircuitBreakerConfig = { timeout: 10000, // If our function takes longer than 10 seconds, trigger a failure errorThresholdPercentage: 80, // When 80% of requests fail, trip the circuit resetTimeout: 30000, // After 30 seconds, try again. rollingCountTimeout: 120000, // the duration of the statistical rolling window, in milliseconds rollingCountBuckets: 120, // the number of buckets the rolling statistical window is divided into volumeThreshold: 10, // minimum number of failures in the circuit errorFilter: defaultErrorFilterFunction // defines the failure filter for the circuit }; common.CircuitBreaker.defaultConfiguration = customDefaultCircuitBreakerConfig;
Note
Le remplacement de la configuration globale des nouvelles tentatives par défaut active les disjoncteurs avec la configuration définie pour tous les clients de service. - Remplacez la configuration du disjoncteur par défaut pour une instance de client donnée. Cet exemple montre comment remplacer le disjoncteur par défaut pour
objectStorageClient
:let customDefaultCircuitBreakerConfig = { timeout: 10000, // If our function takes longer than 10 seconds, trigger a failure errorThresholdPercentage: 80, // When 80% of requests fail, trip the circuit resetTimeout: 30000, // After 30 seconds, try again. rollingCountTimeout: 120000, // the duration of the statistical rolling window, in milliseconds rollingCountBuckets: 120, // the number of buckets the rolling statistical window is divided into volumeThreshold: 10, // minimum number of failures in the circuit errorFilter: defaultErrorFilterFunction, // defines the failure filter for the circuit }; const client = new objectstorage.ObjectStorageClient({authenticationDetailsProvider : provider}, { circuitBreaker : new common.CircuitBreaker(customDefaultCircuitBreakerConfig)});
Priorité du comportement du disjoncteur
Toute configuration définie explicitement au niveau du client remplace la configuration globale par défaut et le remplacement au niveau de l'environnement, pour ce client particulier.
Exemples de circuits
Pour des exemples TypeScript, voir Github.
Pour des exemples JavaScript, voir Github.
Définition des points d'extrémité
Les points d'extrémité de service peuvent être définis de trois façons :
- Définissez .endpoint = '<YOUR_ENDPOINT>' sur l'instance de service. Vous pouvez ainsi spécifier un nom d'hôte complet (par exemple, https://www.example.com).
- Réglez .region = '<YOUR_REGION_ID> sur l'instance de service. Cela sélectionne le nom d'hôte approprié pour le service dans la région indiquée. Toutefois, si le service n'est pas pris en charge dans la région que vous avez définie, la trousse SDK pour TypeScript et JavaScript retourne une erreur. Vous pouvez consulter la liste des ID région dans : ./oci-typescript-sdk/common/lib/region.ts
- Transmettez la région dans le fichier de configuration. Pour plus d'informations, voir Fichier de configuration des trousses SDK et de l'interface de ligne de commande.
Notez qu'une instance de service ne peut pas être utilisée pour communiquer avec différentes régions. Si vous devez faire des demandes à différentes régions, créez plusieurs instances de service.
Points d'extrémité dédiés
La valeur définie au niveau du client est prioritaire sur la valeur définie au niveau de l'application.
Activation des modèles de point d'extrémité propres à un domaine au niveau de l'application :
OCI_REALM_SPECIFIC_SERVICE_ENDPOINT_TEMPLATE_ENABLED
à true
. La valeur booléenne n'est pas sensible à la casse.
Activation des modèles de point d'extrémité propres au domaine au niveau du client :
const client = new os.ObjectStorageClient({ authenticationDetailsProvider: provider });
client.useRealmSpecificEndpointTemplate = true;
Pour des exemples complets, voir les exemples TypeScript et JavaScript sur GitHub.
Prise en charge de la nouvelle région
Si vous utilisez une version de trousse SDK antérieure à l'annonce d'une nouvelle région, vous pouvez utiliser une solution de rechange pour l'atteindre.
Une région est une zone géographique localisée. Pour plus d'informations sur les régions et comment les identifier, voir Régions et domaines de disponibilité.
Un domaine est un jeu de régions qui partagent des entités. Vous pouvez identifier votre domaine en consultant son nom à la fin de l'adresse réseau. Par exemple, le domaine pour xyz.abc.123.oraclecloud.com est oraclecloud.com.
Vous devez d'abord appeler Region.register pour enregistrer la nouvelle région, puis vous pouvez définir la région en utilisant le fichier de configuration ou en définissant .region = <Your_new_registered_region>.
domaine oraclecloud.com
Pour les régions du domaine oraclecloud.com, vous pouvez transmettre de nouveaux noms de région, comme vous transmettriez des noms déjà définis dans l'énumération Région de votre version de trousse SDK.
Pour définir la région :
identityClient = await new identity.IdentityClient({ authenticationDetailsProvider: provider });
identityClient.region = 'us-phoenix-1'
Autres domaines
Pour les régions des domaines autres que oraclecloud.com, vous pouvez utiliser les solutions suivantes pour atteindre de nouvelles régions avec des versions antérieures de la trousse SDK.
Pour définir le point d'extrémité :
// Instantiate an identity client
identityClient = await new identity.IdentityClient({ authenticationDetailsProvider: provider });
identityClient.endpoint = 'https://<your_endpoint>.com'
Réponses paginées
Il est parfois préférable de charger un résultat en différé. Pour extraire plus de données d'un chargement différé, vous devez continuer d'appeler l'opération de liste, en transmettant la valeur du jeton suivant de la réponse la plus récente. Grâce au module de pagination, vous pouvez :
- Charger facilement tous les résultats possibles à partir d'un appel de liste
- Charger les résultats en différé
Pour obtenir un exemple de l'utilisation de ces fonctions, consultez GitHub.
Traitement des exceptions
Lors du traitement d'une exception, vous pouvez obtenir plus d'informations sur la demande HTTP qui l'a générée, notamment le code de statut ou la temporisation. Vous pouvez également obtenir l'ID demande lors du traitement d'une exception en examinant la propriété opcRequestId de l'objet d'erreur.
try {
const response = await identityClient.listAllUsersResponses(listUserReq);
} catch (err) {
console.log('requestId: ', err.opcRequestId);
}
Journalisation
La trousse SDK pour TypeScript et JavaScript vous permet d'intégrer votre propre enregistreur automatique. La connexion à la trousse SDK se fait au moyen de l'interface de l'enregistreur automatique. Cette interface est une abstraction de journalisation qui permet l'utilisation d'une bibliothèque de journalisation fournie par l'utilisateur, comme log4js, bunyan ou winston.
Pour plus d'informations, voir l'exemple de journalisation sur GitHub.
// TypeScript // Download the logger that you want to use with the SDK (like bunyan) import { LOG } from "oci-sdk"; var bunyan = require("bunyan"); // Set the logger here var bunLog = bunyan.createLogger({ name: "LoggingExample", level: "debug" }); LOG.logger = bunLog;
// Javascript
import { LOG } from "oci-sdk";
var bunyan = require("bunyan");
// Set the logger here.
var bunLog = bunyan.createLogger({ name: "LoggingExample", level: "debug" });
LOG.logger = bunLog;