Bug 1914632 - delete the actors during shutdown for worker keepalive requests.r=edenchuang

Differential Revision: https://phabricator.services.mozilla.com/D222437
This commit is contained in:
smayya
2024-09-24 11:30:22 +00:00
parent 250a9f6bba
commit fe6c28d58c
5 changed files with 137 additions and 46 deletions

View File

@@ -309,7 +309,7 @@ bool FetchService::FetchInstance::IsLocalHostFetch() const {
return res;
}
void FetchService::FetchInstance::Cancel() {
void FetchService::FetchInstance::Cancel(bool aForceAbort) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
@@ -320,6 +320,38 @@ void FetchService::FetchInstance::Cancel() {
// FetchInstance::OnResponseEnd() to resolve the pending promises.
// Otherwise, resolving the pending promises here.
if (mFetchDriver) {
// if keepalive is active and it is NOT user initiated Abort, then
// do not cancel the request.
if (mRequest->GetKeepalive() && !aForceAbort) {
FETCH_LOG(("Cleaning up the worker for keepalive[%p]", this));
MOZ_ASSERT(mArgs.is<WorkerFetchArgs>());
if (mArgs.is<WorkerFetchArgs>()) {
// delete the actors for cleanup for worker keep-alive requests.
// Non-worker keepalive requests need actors to be active until request
// completion, because we update request quota per load-group in
// FetchChild::ActorDestroy.
MOZ_ASSERT((mArgs.as<WorkerFetchArgs>().mFetchParentPromise));
if (mArgs.as<WorkerFetchArgs>().mResponseEndPromiseHolder.Exists()) {
FETCH_LOG(
("FetchInstance::Cancel() [%p] mResponseEndPromiseHolder exists",
this));
mArgs.as<WorkerFetchArgs>().mResponseEndPromiseHolder.Disconnect();
MOZ_ASSERT(
!mArgs.as<WorkerFetchArgs>().mFetchParentPromise->IsResolved());
if (!mArgs.as<WorkerFetchArgs>().mFetchParentPromise->IsResolved()) {
// the parent promise resolution leads to deleting of actors
// mActorDying prevents further access to FetchParent
mActorDying = true;
mArgs.as<WorkerFetchArgs>().mFetchParentPromise->Resolve(true,
__func__);
}
}
}
return;
}
mFetchDriver->RunAbortAlgorithm();
return;
}
@@ -367,6 +399,11 @@ void FetchService::FetchInstance::OnResponseEnd(
MOZ_ASSERT(mPromises);
if (mArgs.is<WorkerFetchArgs>() &&
mArgs.as<WorkerFetchArgs>().mResponseEndPromiseHolder.Exists()) {
mArgs.as<WorkerFetchArgs>().mResponseEndPromiseHolder.Complete();
}
if (aReason == eAborted) {
// If ResponseAvailablePromise has not resolved yet, resolved with
// NS_ERROR_DOM_ABORT_ERR response.
@@ -416,7 +453,7 @@ void FetchService::FetchInstance::OnResponseAvailableInternal(
this, body.get()));
MOZ_ASSERT(mRequest);
if (mArgsType != FetchArgsType::NavigationPreload) {
if (mArgsType != FetchArgsType::NavigationPreload && !mActorDying) {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
__func__,
[response = mResponse.clonePtr(), actorID = GetActorID()]() mutable {
@@ -457,7 +494,7 @@ void FetchService::FetchInstance::OnDataAvailable() {
MOZ_ASSERT(mRequest);
if (mArgsType != FetchArgsType::NavigationPreload) {
if (mArgsType != FetchArgsType::NavigationPreload && !mActorDying) {
nsCOMPtr<nsIRunnable> r =
NS_NewRunnableFunction(__func__, [actorID = GetActorID()]() {
FETCH_LOG(("FetchInstance::OnDataAvailable, Runnable"));
@@ -474,7 +511,7 @@ void FetchService::FetchInstance::OnDataAvailable() {
void FetchService::FetchInstance::FlushConsoleReport() {
FETCH_LOG(("FetchInstance::FlushConsoleReport [%p]", this));
if (mArgsType != FetchArgsType::NavigationPreload) {
if (mArgsType != FetchArgsType::NavigationPreload && !mActorDying) {
if (!mReporter) {
return;
}
@@ -517,7 +554,7 @@ void FetchService::FetchInstance::OnReportPerformanceTiming() {
// Force replace initiatorType for ServiceWorkerNavgationPreload.
if (mArgsType == FetchArgsType::NavigationPreload) {
timing.initiatorType() = u"navigation"_ns;
} else {
} else if (!mActorDying) {
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
__func__, [actorID = GetActorID(), timing = timing]() {
FETCH_LOG(("FetchInstance::OnReportPerformanceTiming, Runnable"));
@@ -796,7 +833,7 @@ NS_IMETHODIMP FetchService::Observe(nsISupports* aSubject, const char* aTopic,
if (res) {
return false;
}
entry.Data()->Cancel();
entry.Data()->Cancel(true);
return true;
});
}
@@ -848,7 +885,8 @@ RefPtr<FetchServicePromises> FetchService::Fetch(FetchArgs&& aArgs) {
return promises;
}
void FetchService::CancelFetch(const RefPtr<FetchServicePromises>&& aPromises) {
void FetchService::CancelFetch(const RefPtr<FetchServicePromises>&& aPromises,
bool aForceAbort) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aPromises);
@@ -858,11 +896,22 @@ void FetchService::CancelFetch(const RefPtr<FetchServicePromises>&& aPromises) {
if (entry) {
// Notice any modifications here before entry.Remove() probably should be
// reflected to Observe() offline case.
entry.Data()->Cancel();
entry.Data()->Cancel(aForceAbort);
entry.Remove();
FETCH_LOG(
("FetchService::CancelFetch entry [%p] removed", aPromises.get()));
}
}
MozPromiseRequestHolder<FetchServiceResponseEndPromise>&
FetchService::GetResponseEndPromiseHolder(
const RefPtr<FetchServicePromises>& aPromises) {
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aPromises);
auto entry = mFetchInstanceTable.Lookup(aPromises);
MOZ_ASSERT(entry);
return entry.Data()->GetResponseEndPromiseHolder();
}
} // namespace mozilla::dom