Support empty offers for serverless accounts (#132)

* Add support for no offers when serverless accounts

* Add workaround for ignoring failed /offers when using connection string

* Revert @azure/cosmos upgrade
This commit is contained in:
Tanuj Mittal 2020-08-14 17:45:13 -07:00 committed by GitHub
parent 2752d6af00
commit 22b2e1df48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 41 deletions

View File

@ -454,6 +454,10 @@ export function readCollectionQuotaInfo(
}
export function readOffers(options: any): Q.Promise<DataModels.Offer[]> {
if (options.isServerless) {
return Q([]); // Reading offers is not supported for serverless accounts
}
try {
if (configContext.platform === Platform.Portal) {
return sendCachedDataMessage<DataModels.Offer[]>(MessageTypes.AllOffers, [
@ -469,6 +473,13 @@ export function readOffers(options: any): Q.Promise<DataModels.Offer[]> {
.offers.readAll()
.fetchAll()
.then(response => response.resources)
.catch(error => {
// This should be removed when we can correctly identify if an account is serverless when connected using connection string too.
if (error.message.includes("Reading or replacing offers is not supported for serverless accounts")) {
return [];
}
throw error;
})
);
}

View File

@ -1475,38 +1475,33 @@ export default class Explorer {
);
};
if (this.isServerlessEnabled()) {
// Serverless accounts don't support offers call
refreshDatabases();
} else {
const offerPromise: Q.Promise<DataModels.Offer[]> = readOffers();
this._setLoadingStatusText("Fetching offers...");
offerPromise.then(
(offers: DataModels.Offer[]) => {
this._setLoadingStatusText("Successfully fetched offers.");
refreshDatabases(offers);
},
error => {
this._setLoadingStatusText("Failed to fetch offers.");
this.isRefreshingExplorer(false);
deferred.reject(error);
TelemetryProcessor.traceFailure(
Action.LoadDatabases,
{
databaseAccountName: this.databaseAccount().name,
defaultExperience: this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree,
error: JSON.stringify(error)
},
startKey
);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Error while refreshing databases: ${JSON.stringify(error)}`
);
}
);
}
const offerPromise: Q.Promise<DataModels.Offer[]> = readOffers({ isServerless: this.isServerlessEnabled() });
this._setLoadingStatusText("Fetching offers...");
offerPromise.then(
(offers: DataModels.Offer[]) => {
this._setLoadingStatusText("Successfully fetched offers.");
refreshDatabases(offers);
},
error => {
this._setLoadingStatusText("Failed to fetch offers.");
this.isRefreshingExplorer(false);
deferred.reject(error);
TelemetryProcessor.traceFailure(
Action.LoadDatabases,
{
databaseAccountName: this.databaseAccount().name,
defaultExperience: this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree,
error: JSON.stringify(error)
},
startKey
);
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Error while refreshing databases: ${JSON.stringify(error)}`
);
}
);
return deferred.promise.then(
() => {

View File

@ -648,7 +648,9 @@ export default class Collection implements ViewModels.Collection {
});
// TODO: Use the collection entity cache to get quota info
const quotaInfoPromise: Q.Promise<DataModels.CollectionQuotaInfo> = readCollectionQuotaInfo(this);
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = readOffers();
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = readOffers({
isServerless: this.container.isServerlessEnabled()
});
Q.all([quotaInfoPromise, offerInfoPromise]).then(
() => {
this.container.isRefreshingExplorer(false);
@ -657,9 +659,7 @@ export default class Collection implements ViewModels.Collection {
const quotaInfo = _.omit(quotaInfoWithUniqueKeyPolicy, "uniqueKeyPolicy");
const collectionOffer = this._getOfferForCollection(offerInfoPromise.valueOf(), collectionDataModel);
const isDatabaseShared = this.getDatabase() && this.getDatabase().isDatabaseShared();
const isServerless = this.container.isServerlessEnabled();
if ((isDatabaseShared || isServerless) && !collectionOffer) {
if (!collectionOffer) {
this.quotaInfo(quotaInfo);
TelemetryProcessor.traceSuccess(
Action.LoadOffers,

View File

@ -123,10 +123,6 @@ export default class Database implements ViewModels.Database {
public readSettings(): Q.Promise<void> {
const deferred: Q.Deferred<void> = Q.defer<void>();
if (this.container.isServerlessEnabled()) {
deferred.resolve();
}
this.container.isRefreshingExplorer(true);
const databaseDataModel: DataModels.Database = <DataModels.Database>{
id: this.id(),
@ -138,7 +134,9 @@ export default class Database implements ViewModels.Database {
defaultExperience: this.container.defaultExperience()
});
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = readOffers();
const offerInfoPromise: Q.Promise<DataModels.Offer[]> = readOffers({
isServerless: this.container.isServerlessEnabled()
});
Q.all([offerInfoPromise]).then(
() => {
this.container.isRefreshingExplorer(false);
@ -147,6 +145,11 @@ export default class Database implements ViewModels.Database {
offerInfoPromise.valueOf(),
databaseDataModel
);
if (!databaseOffer) {
return;
}
readOffer(databaseOffer).then((offerDetail: DataModels.OfferWithHeaders) => {
const offerThroughputInfo: DataModels.OfferThroughputInfo = {
minimumRUForCollection: