Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=2 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "DetailedPromise.h"
8 : #include "mozilla/dom/DOMException.h"
9 : #include "nsPrintfCString.h"
10 :
11 : namespace mozilla {
12 : namespace dom {
13 :
14 0 : DetailedPromise::DetailedPromise(nsIGlobalObject* aGlobal,
15 0 : const nsACString& aName)
16 : : Promise(aGlobal)
17 : , mName(aName)
18 : , mResponded(false)
19 0 : , mStartTime(TimeStamp::Now())
20 : {
21 0 : }
22 :
23 0 : DetailedPromise::DetailedPromise(nsIGlobalObject* aGlobal,
24 : const nsACString& aName,
25 : Telemetry::HistogramID aSuccessLatencyProbe,
26 0 : Telemetry::HistogramID aFailureLatencyProbe)
27 0 : : DetailedPromise(aGlobal, aName)
28 : {
29 0 : mSuccessLatencyProbe.Construct(aSuccessLatencyProbe);
30 0 : mFailureLatencyProbe.Construct(aFailureLatencyProbe);
31 0 : }
32 :
33 0 : DetailedPromise::~DetailedPromise()
34 : {
35 : // It would be nice to assert that mResponded is identical to
36 : // GetPromiseState() == PromiseState::Rejected. But by now we've been
37 : // unlinked, so don't have a reference to our actual JS Promise object
38 : // anymore.
39 0 : MaybeReportTelemetry(kFailed);
40 0 : }
41 :
42 : void
43 0 : DetailedPromise::MaybeReject(nsresult aArg, const nsACString& aReason)
44 : {
45 : nsPrintfCString msg("%s promise rejected 0x%" PRIx32 " '%s'", mName.get(),
46 0 : static_cast<uint32_t>(aArg), PromiseFlatCString(aReason).get());
47 0 : EME_LOG("%s", msg.get());
48 :
49 0 : MaybeReportTelemetry(kFailed);
50 :
51 0 : LogToBrowserConsole(NS_ConvertUTF8toUTF16(msg));
52 :
53 0 : ErrorResult rv;
54 0 : rv.ThrowDOMException(aArg, aReason);
55 0 : Promise::MaybeReject(rv);
56 0 : }
57 :
58 : void
59 0 : DetailedPromise::MaybeReject(ErrorResult&, const nsACString& aReason)
60 : {
61 0 : NS_NOTREACHED("nsresult expected in MaybeReject()");
62 0 : }
63 :
64 : /* static */ already_AddRefed<DetailedPromise>
65 0 : DetailedPromise::Create(nsIGlobalObject* aGlobal,
66 : ErrorResult& aRv,
67 : const nsACString& aName)
68 : {
69 0 : RefPtr<DetailedPromise> promise = new DetailedPromise(aGlobal, aName);
70 0 : promise->CreateWrapper(nullptr, aRv);
71 0 : return aRv.Failed() ? nullptr : promise.forget();
72 : }
73 :
74 : /* static */ already_AddRefed<DetailedPromise>
75 0 : DetailedPromise::Create(nsIGlobalObject* aGlobal,
76 : ErrorResult& aRv,
77 : const nsACString& aName,
78 : Telemetry::HistogramID aSuccessLatencyProbe,
79 : Telemetry::HistogramID aFailureLatencyProbe)
80 : {
81 0 : RefPtr<DetailedPromise> promise = new DetailedPromise(aGlobal, aName, aSuccessLatencyProbe, aFailureLatencyProbe);
82 0 : promise->CreateWrapper(nullptr, aRv);
83 0 : return aRv.Failed() ? nullptr : promise.forget();
84 : }
85 :
86 : void
87 0 : DetailedPromise::MaybeReportTelemetry(eStatus aStatus)
88 : {
89 0 : if (mResponded) {
90 0 : return;
91 : }
92 0 : mResponded = true;
93 0 : if (!mSuccessLatencyProbe.WasPassed() || !mFailureLatencyProbe.WasPassed()) {
94 0 : return;
95 : }
96 0 : uint32_t latency = (TimeStamp::Now() - mStartTime).ToMilliseconds();
97 0 : EME_LOG("%s %s latency %ums reported via telemetry", mName.get(),
98 : ((aStatus == kSucceeded) ? "succcess" : "failure"), latency);
99 0 : Telemetry::HistogramID tid = (aStatus == kSucceeded) ? mSuccessLatencyProbe.Value()
100 0 : : mFailureLatencyProbe.Value();
101 0 : Telemetry::Accumulate(tid, latency);
102 : }
103 :
104 : } // namespace dom
105 : } // namespace mozilla
|