Backed out 4 changesets (bug 1541238, bug 1542069, bug 1533363) for build bustages - missing bug 1536488 a=backout
authorBogdan Tara <btara@mozilla.com>
Mon, 15 Apr 2019 16:17:04 +0300
changeset 526179 ca196717df0793c823865553b8907cf28573597f
parent 526178 74c650902989c6b30b913c4b20639bf71ba11aef
child 526180 ba9e2244282a6b4a27f93e26a902e63c900ae43d
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1541238, 1542069, 1533363, 1536488
milestone67.0
backs out74c650902989c6b30b913c4b20639bf71ba11aef
cacfa16943741680d75d8e4812c15a63de1b5084
e27ad01b9daa2da02cca20e94b9d60ca862a21d4
a258da1f2a67b56af0f3fe8d817eb84a433c53c6
Backed out 4 changesets (bug 1541238, bug 1542069, bug 1533363) for build bustages - missing bug 1536488 a=backout Backed out changeset 74c650902989 (bug 1541238) Backed out changeset cacfa1694374 (bug 1542069) Backed out changeset e27ad01b9daa (bug 1533363) Backed out changeset a258da1f2a67 (bug 1533363)
modules/libpref/init/StaticPrefList.h
modules/libpref/init/all.js
netwerk/protocol/http/HttpTrafficAnalyzer.cpp
netwerk/protocol/http/HttpTrafficAnalyzer.h
netwerk/protocol/http/HttpTrafficAnalyzer.inc
netwerk/protocol/http/moz.build
netwerk/protocol/http/nsAHttpConnection.h
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
netwerk/protocol/http/nsHttpConnection.cpp
netwerk/protocol/http/nsHttpConnection.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsHttpTransaction.cpp
netwerk/protocol/http/nsHttpTransaction.h
toolkit/components/telemetry/Histograms.json
toolkit/components/telemetry/Scalars.yaml
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -1975,29 +1975,16 @@ PREF("network.predictor.cleaned-up", boo
 
 // A testing flag.
 VARCACHE_PREF(
   "network.predictor.doing-tests",
    network_predictor_doing_tests,
   bool, false
 )
 
-// Telemetry of traffic categories
-VARCACHE_PREF(
-  "network.traffic_analyzer.enabled",
-  network_traffic_analyzer_enabled,
-  RelaxedAtomicBool, false
-)
-
-VARCACHE_PREF(
-  "network.delay.tracking.load",
-   network_delay_tracking_load,
-   uint32_t, 0
-)
-
 //---------------------------------------------------------------------------
 // ContentSessionStore prefs
 //---------------------------------------------------------------------------
 // Maximum number of bytes of DOMSessionStorage data we collect per origin.
 VARCACHE_PREF(
   "browser.sessionstore.dom_storage_limit",
   browser_sessionstore_dom_storage_limit,
   uint32_t, 2048
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5608,19 +5608,16 @@ pref("network.trr.blacklist-duration", 6
 pref("network.trr.request-timeout", 1500);
 // Allow AAAA entries to be used "early", before the A results are in
 pref("network.trr.early-AAAA", false);
 // Explicitly disable ECS (EDNS Client Subnet, RFC 7871)
 pref("network.trr.disable-ECS", true);
 // After this many failed TRR requests in a row, consider TRR borked
 pref("network.trr.max-fails", 5);
 
-// enable HttpTrafficAnalyzer
-pref("network.traffic_analyzer.enabled", true);
-
 pref("captivedetect.canonicalURL", "http://detectportal.firefox.com/success.txt");
 pref("captivedetect.canonicalContent", "success\n");
 pref("captivedetect.maxWaitingTime", 5000);
 pref("captivedetect.pollingTime", 3000);
 pref("captivedetect.maxRetryCount", 5);
 
 #ifdef RELEASE_OR_BETA
 pref("dom.forms.inputmode", false);
deleted file mode 100644
--- a/netwerk/protocol/http/HttpTrafficAnalyzer.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "HttpTrafficAnalyzer.h"
-#include "HttpLog.h"
-
-#include "mozilla/StaticPrefs.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/Unused.h"
-
-namespace mozilla {
-namespace net {
-
-#define DEFINE_CATEGORY(_name, _idx) NS_LITERAL_CSTRING("Y=" #_idx "|" #_name),
-static const nsCString gKeyName[] = {
-#include "HttpTrafficAnalyzer.inc"
-};
-#undef DEFINE_CATEGORY
-
-// ----------------------------------------------------
-// | Flags                           |   Load Type    |
-// ----------------------------------------------------
-// | nsIClassOfService::Leader       |       A        |
-// | w/o nsIRequest::LOAD_BACKGROUND |       B        |
-// | w/ nsIRequest::LOAD_BACKGROUND  |       C        |
-// ----------------------------------------------------
-// | Category                        | List Category  |
-// ----------------------------------------------------
-// | Content                         |       I        |
-// | Basic Disconnected List         |      II        |
-// | Fingerprinting                  |     III        |
-// ----------------------------------------------------
-// ====================================================
-// | Normal Mode                                      |
-// ----------------------------------------------------
-// | Y = 0 for first party                            |
-// | Y = 1 for non-listed third party type            |
-// ----------------------------------------------------
-// |          \Y\          | Type A | Type B | Type C |
-// ----------------------------------------------------
-// | Category I            |    2   |    3   |    4   |
-// | Category II           |    5   |    6   |    7   |
-// | Category III          |    8   |    9   |   10   |
-// ====================================================
-// | Private Mode                                     |
-// ----------------------------------------------------
-// | Y = 11 for first party                           |
-// | Y = 12 for non-listed third party type           |
-// ----------------------------------------------------
-// |          \Y\          | Type A | Type B | Type C |
-// ----------------------------------------------------
-// | Category I            |   13   |   14   |   15   |
-// | Category II           |   16   |   17   |   18   |
-// | Category III          |   19   |   20   |   21   |
-// ====================================================
-
-HttpTrafficCategory HttpTrafficAnalyzer::CreateTrafficCategory(
-    bool aIsPrivateMode, bool aIsThirdParty, ClassOfService aClassOfService,
-    TrackingClassification aClassification) {
-  uint8_t category = aIsPrivateMode ? 11 : 0;
-  if (!aIsThirdParty) {
-    return static_cast<HttpTrafficCategory>(category);
-  }
-
-  switch (aClassification) {
-    case TrackingClassification::eNone:
-      return static_cast<HttpTrafficCategory>(category + 1);
-    case TrackingClassification::eBasic:
-      category += 2;
-      break;
-    case TrackingClassification::eContent:
-      category += 5;
-      break;
-    case TrackingClassification::eFingerprinting:
-      category += 8;
-      break;
-    default:
-      MOZ_ASSERT(false, "incorrect classification");
-      return HttpTrafficCategory::eInvalid;
-  }
-
-  switch (aClassOfService) {
-    case ClassOfService::eLeader:
-      return static_cast<HttpTrafficCategory>(category);
-    case ClassOfService::eBackground:
-      return static_cast<HttpTrafficCategory>(category + 1);
-    case ClassOfService::eOther:
-      return static_cast<HttpTrafficCategory>(category + 2);
-  }
-
-  MOZ_ASSERT(false, "incorrect class of service");
-  return HttpTrafficCategory::eInvalid;
-}
-
-nsresult HttpTrafficAnalyzer::IncrementHttpTransaction(
-    HttpTrafficCategory aCategory) {
-  MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-  MOZ_ASSERT(StaticPrefs::network_traffic_analyzer_enabled());
-  MOZ_ASSERT(aCategory != HttpTrafficCategory::eInvalid, "invalid category");
-
-  LOG(("HttpTrafficAnalyzer::IncrementHttpTransaction [%s] [this=%p]\n",
-       gKeyName[aCategory].get(), this));
-
-  Telemetry::AccumulateCategoricalKeyed(
-      gKeyName[aCategory],
-      Telemetry::LABELS_HTTP_TRAFFIC_ANALYSIS::Transaction);
-  return NS_OK;
-}
-
-nsresult HttpTrafficAnalyzer::IncrementHttpConnection(
-    HttpTrafficCategory aCategory) {
-  MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-  MOZ_ASSERT(StaticPrefs::network_traffic_analyzer_enabled());
-  MOZ_ASSERT(aCategory != HttpTrafficCategory::eInvalid, "invalid category");
-
-  LOG(("HttpTrafficAnalyzer::IncrementHttpConnection [%s] [this=%p]\n",
-       gKeyName[aCategory].get(), this));
-
-  Telemetry::AccumulateCategoricalKeyed(
-      gKeyName[aCategory], Telemetry::LABELS_HTTP_TRAFFIC_ANALYSIS::Connection);
-  return NS_OK;
-}
-
-nsresult HttpTrafficAnalyzer::IncrementHttpConnection(
-    nsTArray<HttpTrafficCategory> &&aCategories) {
-  MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-  MOZ_ASSERT(StaticPrefs::network_traffic_analyzer_enabled());
-  MOZ_ASSERT(!aCategories.IsEmpty(), "empty category");
-
-  nsTArray<HttpTrafficCategory> categories(std::move(aCategories));
-
-  LOG(("HttpTrafficAnalyzer::IncrementHttpConnection size=%" PRIuPTR
-       " [this=%p]\n",
-       categories.Length(), this));
-
-  // divide categories into 4 parts:
-  //   1) normal 1st-party (Y = 0)
-  //   2) normal 3rd-party (0 < Y < 11)
-  //   3) private 1st-party (Y = 11)
-  //   4) private 3rd-party (11 < Y < 22)
-  // Normal and private transaction should not share the same connection,
-  // and we choose 3rd-party prior than 1st-party.
-  HttpTrafficCategory best = categories[0];
-  if ((best == 0 || best == 11) && categories.Length() > 1) {
-    best = categories[1];
-  }
-  Unused << IncrementHttpConnection(best);
-
-  return NS_OK;
-}
-
-#define CLAMP_U32(num) \
-  Clamp<uint32_t>(num, 0, std::numeric_limits<uint32_t>::max())
-
-nsresult HttpTrafficAnalyzer::AccumulateHttpTransferredSize(
-    HttpTrafficCategory aCategory, uint64_t aBytesRead, uint64_t aBytesSent) {
-  MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-  MOZ_ASSERT(StaticPrefs::network_traffic_analyzer_enabled());
-  MOZ_ASSERT(aCategory != HttpTrafficCategory::eInvalid, "invalid category");
-
-  LOG(("HttpTrafficAnalyzer::AccumulateHttpTransferredSize [%s] rb=%" PRIu64 " "
-       "sb=%" PRIu64 " [this=%p]\n",
-       gKeyName[aCategory].get(), aBytesRead, aBytesSent, this));
-
-  // Telemetry supports uint32_t only.
-  auto total = CLAMP_U32(CLAMP_U32(aBytesRead) + CLAMP_U32(aBytesSent));
-  Telemetry::ScalarAdd(Telemetry::ScalarID::NETWORKING_DATA_TRANSFERRED,
-                       NS_ConvertUTF8toUTF16(gKeyName[aCategory]), total);
-  return NS_OK;
-}
-
-}  // namespace net
-}  // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/http/HttpTrafficAnalyzer.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_netwerk_protocol_http_HttpTrafficAnalyzer_h
-#define mozilla_netwerk_protocol_http_HttpTrafficAnalyzer_h
-
-namespace mozilla {
-namespace net {
-
-#define DEFINE_CATEGORY(_name, _idx) e##_name = _idx##u,
-enum HttpTrafficCategory : uint8_t {
-#include "HttpTrafficAnalyzer.inc"
-  eInvalid = 255,
-};
-#undef DEFINE_CATEGORY
-
-class HttpTrafficAnalyzer final {
- public:
-  enum ClassOfService : uint8_t {
-    eLeader = 0,
-    eBackground = 1,
-    eOther = 255,
-  };
-
-  enum TrackingClassification : uint8_t {
-    eNone = 0,
-    eBasic = 1,
-    eContent = 2,
-    eFingerprinting = 3,
-  };
-
-  static HttpTrafficCategory CreateTrafficCategory(
-      bool aIsPrivateMode, bool aIsThirdParty, ClassOfService aClassOfService,
-      TrackingClassification aClassification);
-
-  nsresult IncrementHttpTransaction(HttpTrafficCategory aCategory);
-  nsresult IncrementHttpConnection(HttpTrafficCategory aCategory);
-  nsresult IncrementHttpConnection(nsTArray<HttpTrafficCategory> &&aCategories);
-  nsresult AccumulateHttpTransferredSize(HttpTrafficCategory aCategory,
-                                         uint64_t aBytesRead,
-                                         uint64_t aBytesSent);
-};
-
-}  // namespace net
-}  // namespace mozilla
-
-#endif  // mozilla_netwerk_protocol_http_HttpTrafficAnalyzer_h
deleted file mode 100644
--- a/netwerk/protocol/http/HttpTrafficAnalyzer.inc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Type A) Parser blocking script loads will have an mContentPolicyType
-//         indicating a script load and a nsIClassOfService::Leader class of service.
-// Type B) I couldn’t find a class flag that corresponds to synchronous loads
-//         that block the load event, but I think a simple way to determine
-//         which ones they are is to examine whether the channel belongs to a
-//         load group and do not have a LOAD_BACKGROUND load flag.
-//         If that condition holds, then it is blocking the load event of some document.
-// Type C) I think a simple way to find channels that don’t block document loads
-//         (e.g. XHR and fetch) is to look for those which are in a load group
-//         and have a LOAD_BACKGROUND load flag.
-
-
-// Y=0 - all requests/connections/bytes that are first party.
-DEFINE_CATEGORY(NormalFirstParty, 0)
-
-// Y=1 - all requests/connections/bytes that are third party
-// but don’t fall into other categories
-DEFINE_CATEGORY(NormalThirdPartyOther, 1)
-
-// Y=2 - all requests/connections/bytes associated with third party loads that
-// match the Content Category and have a load of type (A)
-DEFINE_CATEGORY(NormalThirdPartyContentLeader, 2)
-
-// Y=3 - all requests/connections/bytes associated with third party loads that
-// match the Content Category and have a load of type (B)
-DEFINE_CATEGORY(NormalThirdPartyContentBackground, 3)
-
-// Y=4 - all requests/connections/bytes associated with third party loads that
-// match the Content Category and have a load of type (C)
-DEFINE_CATEGORY(NormalThirdPartyContentOther, 4)
-
-// Y=5 - all requests/connections/bytes associated with third party loads that
-// match the Analytics/Social/Advertising (Basic) Category and have a load of type (A)
-DEFINE_CATEGORY(NormalThirdPartyBasicLeader, 5)
-
-// Y=6 - all requests/connections/bytes associated with third party loads that
-// match the Analytics/Social/Advertising (Basic) Category and have a load of type (B)
-DEFINE_CATEGORY(NormalThirdPartyBasicBackground, 6)
-
-// Y=7 - all requests/connections/bytes associated with third party loads that
-// match the Analytics/Social/Advertising (Basic) Category and have a load of type (C)
-DEFINE_CATEGORY(NormalThirdPartyBasicOther, 7)
-
-// Y=8 - all requests/connections/bytes associated with third party loads that
-// match the Fingerprinting Category and have a load of type (A)
-DEFINE_CATEGORY(NormalThirdPartyFingerprintingLeader, 8)
-
-// Y=9 - all requests/connections/bytes associated with third party loads that
-// match the Fingerprinting Category and have a load of type (B)
-DEFINE_CATEGORY(NormalThirdPartyFingerprintingBackground, 9)
-
-// Y=10 - all requests/connections/bytes associated with third party loads that
-// match the Fingerprinting Category and have a load of type (C)
-DEFINE_CATEGORY(NormalThirdPartyFingerprintingOther, 10)
-
-// Y=11 - private mode and all requests/connections/bytes that are first party.
-DEFINE_CATEGORY(PrivateFirstParty, 11)
-
-// Y=12 - private mode and all requests/connections/bytes that are third party
-// but don’t fall into other categories
-DEFINE_CATEGORY(PrivateThirdPartyOther, 12)
-
-// Y=13 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Content Category and have a load of type (A)
-DEFINE_CATEGORY(PrivateThirdPartyContentLeader, 13)
-
-// Y=14 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Content Category and have a load of type (B)
-DEFINE_CATEGORY(PrivateThirdPartyContentBackground, 14)
-
-// Y=15 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Content Category and have a load of type (C)
-DEFINE_CATEGORY(PrivateThirdPartyContentOther, 15)
-
-// Y=16 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Analytics/Social/Advertising (Basic) Category
-// and have a load of type (A)
-DEFINE_CATEGORY(PrivateThirdPartyBasicLeader, 16)
-
-// Y=17 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Analytics/Social/Advertising (Basic) Category
-// and have a load of type (B)
-DEFINE_CATEGORY(PrivateThirdPartyBasicBackground, 17)
-
-// Y=18 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Analytics/Social/Advertising (Basic) Category
-// and have a load of type (C)
-DEFINE_CATEGORY(PrivateThirdPartyBasicOther, 18)
-
-// Y=19 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Fingerprinting Category and have a load of type (A)
-DEFINE_CATEGORY(PrivateThirdPartyFingerprintingLeader, 19)
-
-// Y=20 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Fingerprinting Category and have a load of type (B)
-DEFINE_CATEGORY(PrivateThirdPartyFingerprintingBackground, 20)
-
-// Y=21 - private mode and all requests/connections/bytes associated with
-// third party loads that match the Fingerprinting Category and have a load of type (C)
-DEFINE_CATEGORY(PrivateThirdPartyFingerprintingOther, 21)
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -79,17 +79,16 @@ UNIFIED_SOURCES += [
     'HttpAuthUtils.cpp',
     'HttpBackgroundChannelChild.cpp',
     'HttpBackgroundChannelParent.cpp',
     'HttpBaseChannel.cpp',
     'HttpChannelChild.cpp',
     'HttpChannelParent.cpp',
     'HttpChannelParentListener.cpp',
     'HttpInfo.cpp',
-    'HttpTrafficAnalyzer.cpp',
     'InterceptedChannel.cpp',
     'InterceptedHttpChannel.cpp',
     'nsCORSListenerProxy.cpp',
     'nsHttp.cpp',
     'nsHttpActivityDistributor.cpp',
     'nsHttpAuthCache.cpp',
     'nsHttpAuthManager.cpp',
     'nsHttpBasicAuth.cpp',
--- a/netwerk/protocol/http/nsAHttpConnection.h
+++ b/netwerk/protocol/http/nsAHttpConnection.h
@@ -144,20 +144,16 @@ class nsAHttpConnection : public nsISupp
   // any thread.
   virtual void SetSecurityCallbacks(nsIInterfaceRequestor *aCallbacks) = 0;
 
   // nsHttp.h version
   virtual HttpVersion Version() = 0;
 
   // A notification of the current active tab id change.
   virtual void TopLevelOuterContentWindowIdChanged(uint64_t windowId) = 0;
-
-  // categories set by nsHttpTransaction to identify how this connection is
-  // being used.
-  virtual void SetTrafficCategory(HttpTrafficCategory) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpConnection, NS_AHTTPCONNECTION_IID)
 
 #define NS_DECL_NSAHTTPCONNECTION(fwdObject)                                  \
   MOZ_MUST_USE nsresult OnHeadersAvailable(                                   \
       nsAHttpTransaction *, nsHttpRequestHead *, nsHttpResponseHead *,        \
       bool *reset) override;                                                  \
@@ -224,19 +220,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpCon
   void SetLastTransactionExpectedNoContent(bool val) override {               \
     if (fwdObject) (fwdObject)->SetLastTransactionExpectedNoContent(val);     \
   }                                                                           \
   int64_t BytesWritten() override {                                           \
     return fwdObject ? (fwdObject)->BytesWritten() : 0;                       \
   }                                                                           \
   void SetSecurityCallbacks(nsIInterfaceRequestor *aCallbacks) override {     \
     if (fwdObject) (fwdObject)->SetSecurityCallbacks(aCallbacks);             \
-  }                                                                           \
-  void SetTrafficCategory(HttpTrafficCategory aCategory) override {           \
-    if (fwdObject) (fwdObject)->SetTrafficCategory(aCategory);                \
   }
 
 // ThrottleResponse deliberately ommited since we want different implementation
 // for h1 and h2 connections.
 
 }  // namespace net
 }  // namespace mozilla
 
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -120,17 +120,16 @@
 #include "nsINetworkLinkService.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/ServiceWorkerUtils.h"
 #include "mozilla/net/AsyncUrlChannelClassifier.h"
 #include "mozilla/net/NeckoChannelParams.h"
 #include "mozilla/net/UrlClassifierFeatureFactory.h"
 #include "nsIWebNavigation.h"
-#include "HttpTrafficAnalyzer.h"
 
 #ifdef MOZ_TASK_TRACER
 #  include "GeckoTaskTracer.h"
 #endif
 
 #ifdef MOZ_GECKO_PROFILER
 #  include "ProfilerMarkerPayload.h"
 #endif
@@ -1239,83 +1238,36 @@ nsresult nsHttpChannel::SetupTransaction
                                 NS_GET_IID(nsIHttpPushListener),
                                 getter_AddRefs(pushListener));
   if (pushListener) {
     mCaps |= NS_HTTP_ONPUSH_LISTENER;
   }
 
   EnsureTopLevelOuterContentWindowId();
 
-  HttpTrafficCategory category = CreateTrafficCategory();
-
   nsCOMPtr<nsIAsyncInputStream> responseStream;
   rv = mTransaction->Init(
       mCaps, mConnectionInfo, &mRequestHead, mUploadStream, mReqContentLength,
       mUploadStreamHasHeaders, GetCurrentThreadEventTarget(), callbacks, this,
-      mTopLevelOuterContentWindowId, category, getter_AddRefs(responseStream));
+      mTopLevelOuterContentWindowId, getter_AddRefs(responseStream));
   if (NS_FAILED(rv)) {
     mTransaction = nullptr;
     return rv;
   }
 
   mTransaction->SetClassOfService(mClassOfService);
   if (EnsureRequestContext()) {
     mTransaction->SetRequestContext(mRequestContext);
   }
 
   rv = nsInputStreamPump::Create(getter_AddRefs(mTransactionPump),
                                  responseStream);
   return rv;
 }
 
-HttpTrafficCategory nsHttpChannel::CreateTrafficCategory() {
-  MOZ_ASSERT(!mFirstPartyClassificationFlags ||
-             !mThirdPartyClassificationFlags);
-
-  if (!StaticPrefs::network_traffic_analyzer_enabled()) {
-    return HttpTrafficCategory::eInvalid;
-  }
-
-  HttpTrafficAnalyzer::ClassOfService cos;
-  {
-    if (mClassOfService & nsIClassOfService::Leader &&
-        mLoadInfo->GetExternalContentPolicyType() ==
-            nsIContentPolicy::TYPE_SCRIPT) {
-      cos = HttpTrafficAnalyzer::ClassOfService::eLeader;
-    } else if (mLoadFlags & nsIRequest::LOAD_BACKGROUND) {
-      cos = HttpTrafficAnalyzer::ClassOfService::eBackground;
-    } else {
-      cos = HttpTrafficAnalyzer::ClassOfService::eOther;
-    }
-  }
-
-  bool isThirdParty = !!mThirdPartyClassificationFlags;
-  HttpTrafficAnalyzer::TrackingClassification tc;
-  {
-    uint32_t flags = isThirdParty ? mThirdPartyClassificationFlags
-                                  : mFirstPartyClassificationFlags;
-
-    using CF = nsIHttpChannel::ClassificationFlags;
-    using TC = HttpTrafficAnalyzer::TrackingClassification;
-
-    if (flags & CF::CLASSIFIED_TRACKING_CONTENT) {
-      tc = TC::eContent;
-    } else if (flags & CF::CLASSIFIED_FINGERPRINTING) {
-      tc = TC::eFingerprinting;
-    } else if (flags & CF::CLASSIFIED_ANY_BASIC_TRACKING) {
-      tc = TC::eBasic;
-    } else {
-      tc = TC::eNone;
-    }
-  }
-
-  return HttpTrafficAnalyzer::CreateTrafficCategory(NS_UsePrivateBrowsing(this),
-                                                    isThirdParty, cos, tc);
-}
-
 enum class Report { Error, Warning };
 
 // Helper Function to report messages to the console when the loaded
 // script had a wrong MIME type.
 void ReportMimeTypeMismatch(nsHttpChannel *aChannel, const char *aMessageName,
                             nsIURI *aURI, const nsACString &aContentType,
                             Report report) {
   NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
@@ -6620,45 +6572,24 @@ nsresult nsHttpChannel::BeginConnect() {
 
   // We are about to do an async lookup to check if the URI is a
   // tracker. If yes, this channel will be canceled by channel classifier.
   // Chances are the lookup is not needed so CheckIsTrackerWithLocalTable()
   // will return an error and then we can BeginConnectActual() right away.
   RefPtr<nsHttpChannel> self = this;
   bool willCallback = NS_SUCCEEDED(
       AsyncUrlChannelClassifier::CheckChannel(this, [self]() -> void {
-        auto nextFunc = [self]() -> void {
-          nsresult rv = self->BeginConnectActual();
-          if (NS_FAILED(rv)) {
-            // Since this error is thrown asynchronously so that the caller
-            // of BeginConnect() will not do clean up for us. We have to do
-            // it on our own.
-            self->CloseCacheEntry(false);
-            Unused << self->AsyncAbort(rv);
-          }
-        };
-
-        uint32_t delayMillisec = StaticPrefs::network_delay_tracking_load();
-        if (self->IsThirdPartyTrackingResource() && delayMillisec) {
-          nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableFunction(
-              "nsHttpChannel::BeginConnect-delayed", nextFunc);
-          nsresult rv = NS_DelayedDispatchToCurrentThread(runnable.forget(),
-                                                          delayMillisec);
-          if (NS_SUCCEEDED(rv)) {
-            LOG(
-                ("nsHttpChannel::BeginConnect delaying 3rd-party tracking "
-                 "resource for %u ms [this=%p]",
-                 delayMillisec, self.get()));
-            return;
-          }
-          LOG(("nsHttpChannel::BeginConnect unable to delay loading. [this=%p]",
-               self.get()));
+        nsresult rv = self->BeginConnectActual();
+        if (NS_FAILED(rv)) {
+          // Since this error is thrown asynchronously so that the caller
+          // of BeginConnect() will not do clean up for us. We have to do
+          // it on our own.
+          self->CloseCacheEntry(false);
+          Unused << self->AsyncAbort(rv);
         }
-
-        nextFunc();
       }));
 
   if (!willCallback) {
     // We can do BeginConnectActual immediately if CheckIsTrackerWithLocalTable
     // is failed. Note that we don't need to handle the failure because
     // BeginConnect() will return synchronously and the caller will be
     // responsible for handling it.
     return BeginConnectActual();
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -445,18 +445,16 @@ class nsHttpChannel final : public HttpB
   MOZ_MUST_USE nsresult ContinueOnStopRequest(nsresult status, bool aIsFromNet,
                                               bool aContentComplete);
 
   void HandleAsyncRedirectChannelToHttps();
   MOZ_MUST_USE nsresult StartRedirectChannelToHttps();
   MOZ_MUST_USE nsresult ContinueAsyncRedirectChannelToURI(nsresult rv);
   MOZ_MUST_USE nsresult OpenRedirectChannel(nsresult rv);
 
-  HttpTrafficCategory CreateTrafficCategory();
-
   /**
    * A function that takes care of reading STS and PKP headers and enforcing
    * STS and PKP load rules. After a secure channel is erected, STS and PKP
    * requires the channel to be trusted or any STS or PKP header data on
    * the channel is ignored. This is called from ProcessResponse.
    */
   MOZ_MUST_USE nsresult ProcessSecurityHeaders();
 
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -967,24 +967,16 @@ void nsHttpConnection::Close(nsresult re
     mTCPKeepaliveTransitionTimer->Cancel();
     mTCPKeepaliveTransitionTimer = nullptr;
   }
   if (mForceSendTimer) {
     mForceSendTimer->Cancel();
     mForceSendTimer = nullptr;
   }
 
-  if (!mTrafficCategory.IsEmpty()) {
-    HttpTrafficAnalyzer *hta = gHttpHandler->GetHttpTrafficAnalyzer();
-    if (hta) {
-      hta->IncrementHttpConnection(std::move(mTrafficCategory));
-      MOZ_ASSERT(mTrafficCategory.IsEmpty());
-    }
-  }
-
   if (NS_FAILED(reason)) {
     if (mIdleMonitoring) EndIdleMonitoring();
 
     mTLSFilter = nullptr;
 
     // The connection and security errors clear out alt-svc mappings
     // in case any previously validated ones are now invalid
     if (((reason == NS_ERROR_NET_RESET) ||
@@ -2659,19 +2651,10 @@ bool nsHttpConnection::NoClientCertAuth(
 bool nsHttpConnection::CanAcceptWebsocket() {
   if (!UsingSpdy()) {
     return true;
   }
 
   return mSpdySession->CanAcceptWebsocket();
 }
 
-void nsHttpConnection::SetTrafficCategory(HttpTrafficCategory aCategory) {
-  MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-  if (aCategory == HttpTrafficCategory::eInvalid ||
-      mTrafficCategory.Contains(aCategory)) {
-    return;
-  }
-  Unused << mTrafficCategory.AppendElement(aCategory);
-}
-
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -12,17 +12,16 @@
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsProxyRelease.h"
 #include "prinrval.h"
 #include "TunnelUtils.h"
 #include "mozilla/Mutex.h"
 #include "ARefBase.h"
 #include "TimingStruct.h"
-#include "HttpTrafficAnalyzer.h"
 
 #include "nsIAsyncInputStream.h"
 #include "nsIAsyncOutputStream.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsITimer.h"
 
 class nsISocketTransport;
 class nsISSLSocketControl;
@@ -247,18 +246,16 @@ class nsHttpConnection final : public ns
   // Return true when the socket this connection is using has not been
   // authenticated using a client certificate.  Before SSL negotiation
   // has finished this returns false.
   bool NoClientCertAuth() const;
 
   // HTTP/2 websocket support
   bool CanAcceptWebsocket();
 
-  void SetTrafficCategory(HttpTrafficCategory aCategory);
-
  private:
   // Value (set in mTCPKeepaliveConfig) indicates which set of prefs to use.
   enum TCPKeepaliveConfig {
     kTCPKeepaliveDisabled = 0,
     kTCPKeepaliveShortLivedConfig,
     kTCPKeepaliveLongLivedConfig
   };
 
@@ -434,18 +431,16 @@ class nsHttpConnection final : public ns
   PRIntervalTime mLastRequestBytesSentTime;
 
  public:
   void BootstrapTimings(TimingStruct times);
 
  private:
   TimingStruct mBootstrappedTimings;
   bool mBootstrappedTimingsSet;
-
-  nsTArray<HttpTrafficCategory> mTrafficCategory;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpConnection, NS_HTTPCONNECTION_IID)
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // nsHttpConnection_h__
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -2640,20 +2640,10 @@ void nsHttpHandler::BlacklistSpdy(const 
   mConnMgr->BlacklistSpdy(ci);
   mBlacklistedSpdyOrigins.PutEntry(ci->GetOrigin());
 }
 
 bool nsHttpHandler::IsSpdyBlacklisted(const nsHttpConnectionInfo *ci) {
   return mBlacklistedSpdyOrigins.Contains(ci->GetOrigin());
 }
 
-HttpTrafficAnalyzer *nsHttpHandler::GetHttpTrafficAnalyzer() {
-  MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-
-  if (!StaticPrefs::network_traffic_analyzer_enabled()) {
-    return nullptr;
-  }
-
-  return &mHttpTrafficAnalyzer;
-}
-
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -5,17 +5,16 @@
 
 #ifndef nsHttpHandler_h__
 #define nsHttpHandler_h__
 
 #include "nsHttp.h"
 #include "nsHttpAuthCache.h"
 #include "nsHttpConnectionMgr.h"
 #include "ASpdySession.h"
-#include "HttpTrafficAnalyzer.h"
 
 #include "mozilla/Mutex.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
 #include "nsWeakReference.h"
 
@@ -408,18 +407,16 @@ class nsHttpHandler final : public nsIHt
   // mLastActiveTabLoadOptimizationHit timestamp to now.
   void NotifyActiveTabLoadOptimization();
   TimeStamp const GetLastActiveTabLoadOptimizationHit();
   void SetLastActiveTabLoadOptimizationHit(TimeStamp const &when);
   bool IsBeforeLastActiveTabLoadOptimization(TimeStamp const &when);
 
   bool DumpHpackTables() { return mDumpHpackTables; }
 
-  HttpTrafficAnalyzer *GetHttpTrafficAnalyzer();
-
  private:
   nsHttpHandler();
 
   virtual ~nsHttpHandler();
 
   MOZ_MUST_USE nsresult Init();
 
   //
@@ -659,18 +656,16 @@ class nsHttpHandler final : public nsIHt
   uint32_t mFastOpenStallsLimit;
   uint32_t mFastOpenStallsCounter;
   uint32_t mFastOpenStallsIdleTime;
   uint32_t mFastOpenStallsTimeout;
 
   // If true, the transactions from active tab will be dispatched first.
   bool mActiveTabPriority;
 
-  HttpTrafficAnalyzer mHttpTrafficAnalyzer;
-
  private:
   // For Rate Pacing Certain Network Events. Only assign this pointer on
   // socket thread.
   void MakeNewRequestTokenBucket();
   RefPtr<EventTokenBucket> mRequestTokenBucket;
 
  public:
   // Socket thread only
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -141,18 +141,17 @@ nsHttpTransaction::nsHttpTransaction()
       mTopLevelOuterContentWindowId(0),
       mSubmittedRatePacing(false),
       mPassedRatePacing(false),
       mSynchronousRatePaceRequest(false),
       mClassOfService(0),
       m0RTTInProgress(false),
       mDoNotTryEarlyData(false),
       mEarlyDataDisposition(EARLY_NONE),
-      mFastOpenStatus(TFO_NOT_TRIED),
-      mTrafficCategory(HttpTrafficCategory::eInvalid) {
+      mFastOpenStatus(TFO_NOT_TRIED) {
   this->mSelfAddr.inet = {};
   this->mPeerAddr.inet = {};
   LOG(("Creating nsHttpTransaction @%p\n", this));
 
 #ifdef MOZ_VALGRIND
   memset(&mSelfAddr, 0, sizeof(NetAddr));
   memset(&mPeerAddr, 0, sizeof(NetAddr));
 #endif
@@ -257,32 +256,29 @@ nsHttpTransaction::~nsHttpTransaction() 
   }
 }
 
 nsresult nsHttpTransaction::Init(
     uint32_t caps, nsHttpConnectionInfo *cinfo, nsHttpRequestHead *requestHead,
     nsIInputStream *requestBody, uint64_t requestContentLength,
     bool requestBodyHasHeaders, nsIEventTarget *target,
     nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink,
-    uint64_t topLevelOuterContentWindowId, HttpTrafficCategory trafficCategory,
-    nsIAsyncInputStream **responseBody) {
+    uint64_t topLevelOuterContentWindowId, nsIAsyncInputStream **responseBody) {
   nsresult rv;
 
   LOG1(("nsHttpTransaction::Init [this=%p caps=%x]\n", this, caps));
 
   MOZ_ASSERT(cinfo);
   MOZ_ASSERT(requestHead);
   MOZ_ASSERT(target);
   MOZ_ASSERT(NS_IsMainThread());
 
   mTopLevelOuterContentWindowId = topLevelOuterContentWindowId;
   LOG(("  window-id = %" PRIx64, mTopLevelOuterContentWindowId));
 
-  mTrafficCategory = trafficCategory;
-
   mActivityDistributor = services::GetActivityDistributor();
   if (!mActivityDistributor) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   bool activityDistributorActive;
   rv = mActivityDistributor->GetIsActive(&activityDistributorActive);
   if (NS_SUCCEEDED(rv) && activityDistributorActive) {
@@ -523,26 +519,16 @@ void nsHttpTransaction::SetConnection(ns
 
 void nsHttpTransaction::OnActivated() {
   MOZ_ASSERT(OnSocketThread());
 
   if (mActivated) {
     return;
   }
 
-  if (mTrafficCategory != HttpTrafficCategory::eInvalid) {
-    HttpTrafficAnalyzer *hta = gHttpHandler->GetHttpTrafficAnalyzer();
-    if (hta) {
-      hta->IncrementHttpTransaction(mTrafficCategory);
-    }
-    if (mConnection) {
-      mConnection->SetTrafficCategory(mTrafficCategory);
-    }
-  }
-
   if (mConnection && mRequestHead &&
       mConnection->Version() >= HttpVersion::v2_0) {
     // So this is fun. On http/2, we want to send TE: Trailers, to be
     // spec-compliant. So we add it to the request head here. The fun part
     // is that adding a header to the request head at this point has no
     // effect on what we send on the wire, as the headers are already
     // flattened (in Init()) by the time we get here. So the *real* adding
     // of the header happens in the h2 compression code. We still have to
@@ -1182,24 +1168,16 @@ void nsHttpTransaction::Close(nsresult r
   // EOF or an error still require an end time be recorded.
   if (TimingEnabled()) {
     const TimingStruct timings = Timings();
     if (timings.responseEnd.IsNull() && !timings.responseStart.IsNull()) {
       SetResponseEnd(TimeStamp::Now());
     }
   }
 
-  if (mTrafficCategory != HttpTrafficCategory::eInvalid) {
-    HttpTrafficAnalyzer *hta = gHttpHandler->GetHttpTrafficAnalyzer();
-    if (hta) {
-      hta->AccumulateHttpTransferredSize(mTrafficCategory, mTransferSize,
-                                         mContentRead);
-    }
-  }
-
   if (relConn && mConnection) {
     MutexAutoLock lock(mLock);
     mConnection = nullptr;
   }
 
   mStatus = reason;
   mTransactionDone = true;  // forcibly flag the transaction as complete
   mClosed = true;
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -75,23 +75,25 @@ class nsHttpTransaction final : public n
   // @param topLevelOuterContentWindowId
   //        indicate the top level outer content window in which
   //        this transaction is being loaded.
   // @param responseBody
   //        the input stream that will contain the response data.  async
   //        wait on this input stream for data.  on first notification,
   //        headers should be available (check transaction status).
   //
-  MOZ_MUST_USE nsresult
-  Init(uint32_t caps, nsHttpConnectionInfo *connInfo,
-       nsHttpRequestHead *reqHeaders, nsIInputStream *reqBody,
-       uint64_t reqContentLength, bool reqBodyIncludesHeaders,
-       nsIEventTarget *consumerTarget, nsIInterfaceRequestor *callbacks,
-       nsITransportEventSink *eventsink, uint64_t topLevelOuterContentWindowId,
-       HttpTrafficCategory trafficCategory, nsIAsyncInputStream **responseBody);
+  MOZ_MUST_USE nsresult Init(uint32_t caps, nsHttpConnectionInfo *connInfo,
+                             nsHttpRequestHead *reqHeaders,
+                             nsIInputStream *reqBody, uint64_t reqContentLength,
+                             bool reqBodyIncludesHeaders,
+                             nsIEventTarget *consumerTarget,
+                             nsIInterfaceRequestor *callbacks,
+                             nsITransportEventSink *eventsink,
+                             uint64_t topLevelOuterContentWindowId,
+                             nsIAsyncInputStream **responseBody);
 
   void OnActivated() override;
 
   // attributes
   nsHttpResponseHead *ResponseHead() {
     return mHaveAllHeaders ? mResponseHead : nullptr;
   }
   nsISupports *SecurityInfo() { return mSecurityInfo; }
@@ -477,16 +479,14 @@ class nsHttpTransaction final : public n
     EARLY_ACCEPTED,
     EARLY_425
   } mEarlyDataDisposition;
 
   uint8_t mFastOpenStatus;
 
   // H2 websocket support
   RefPtr<SpdyConnectTransaction> mH2WSTransaction;
-
-  HttpTrafficCategory mTrafficCategory;
 };
 
 }  // namespace net
 }  // namespace mozilla
 
 #endif  // nsHttpTransaction_h__
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -14601,24 +14601,10 @@
           "IDB_InitDirectory",
           "IDB_GetFileSize",
           "IDB_GetWalFileSize",
           "IDB_GetUsage",
           "IDB_RemoveDBFiles"
       ],
       "keyed": true,
       "description": "Getting the number of errors in QuotaManager initialization."
-  },
-  "HTTP_TRAFFIC_ANALYSIS": {
-    "record_in_processes": ["main"],
-    "alert_emails": ["gachen@mozilla.com"],
-    "bug_numbers": [1533363],
-    "expires_in_version": "73",
-    "kind": "categorical",
-    "n_values": 8,
-    "labels": [
-      "Connection",
-      "Transaction"
-    ],
-    "keyed": true,
-    "description": "Numbers of HTTP transactions and connections by type. There are some categories separated by keys based on 4 parameters: 1. normal browsing or private browsing 2. first party or third party 3. class of service 4. tracking classification. Available keys are: ['Y=0|NormalFirstParty', 'Y=1|NormalThirdPartyOther', 'Y=2|NormalThirdPartyContentLeader', 'Y=3|NormalThirdPartyContentBackground', 'Y=4|NormalThirdPartyContentOther', 'Y=5|NormalThirdPartyBasicLeader', 'Y=6|NormalThirdPartyBasicBackground', 'Y=7|NormalThirdPartyBasicOther', 'Y=8|NormalThirdPartyFingerprintingLeader', 'Y=9|NormalThirdPartyFingerprintingBackground', 'Y=10|NormalThirdPartyFingerprintingOther', 'Y=11|PrivateFirstParty', 'Y=12|PrivateThirdPartyOther', 'Y=13|PrivateThirdPartyContentLeader', 'Y=14|PrivateThirdPartyContentBackground', 'Y=15|PrivateThirdPartyContentOther', 'Y=16|PrivateThirdPartyBasicLeader', 'Y=17|PrivateThirdPartyBasicBackground', 'Y=18|PrivateThirdPartyBasicOther', 'Y=19|PrivateThirdPartyFingerprintingLeader', 'Y=20|PrivateThirdPartyFingerprintingBackground', 'Y=21|PrivateThirdPartyFingerprintingOther']."
   }
 }
--- a/toolkit/components/telemetry/Scalars.yaml
+++ b/toolkit/components/telemetry/Scalars.yaml
@@ -2655,59 +2655,16 @@ script.preloader:
     kind: uint
     notification_emails:
       - dothayer@mozilla.com
     release_channel_collection: opt-out
     record_in_processes:
       - 'main'
       - 'content'
 
-networking:
-  data_transferred:
-    bug_numbers:
-      - 1533363
-    description: >
-      How many bytes of HTTP data transferred by type, there are some categories
-      separated by keys based on 4 parameters:
-        1. normal browsing or private browsing
-        2. first party or third party
-        3. class of service
-        4. tracking classification
-
-      Available keys are:
-        Y=0|NormalFirstParty
-        Y=1|NormalThirdPartyOther
-        Y=2|NormalThirdPartyContentLeader
-        Y=3|NormalThirdPartyContentBackground
-        Y=4|NormalThirdPartyContentOther
-        Y=5|NormalThirdPartyBasicLeader
-        Y=6|NormalThirdPartyBasicBackground
-        Y=7|NormalThirdPartyBasicOther
-        Y=8|NormalThirdPartyFingerprintingLeader
-        Y=9|NormalThirdPartyFingerprintingBackground
-        Y=10|NormalThirdPartyFingerprintingOther
-        Y=11|PrivateFirstParty
-        Y=12|PrivateThirdPartyOther
-        Y=13|PrivateThirdPartyContentLeader
-        Y=14|PrivateThirdPartyContentBackground
-        Y=15|PrivateThirdPartyContentOther
-        Y=16|PrivateThirdPartyBasicLeader
-        Y=17|PrivateThirdPartyBasicBackground
-        Y=18|PrivateThirdPartyBasicOther
-        Y=19|PrivateThirdPartyFingerprintingLeader
-        Y=20|PrivateThirdPartyFingerprintingBackground
-        Y=21|PrivateThirdPartyFingerprintingOther
-    expires: "73"
-    keyed: true
-    kind: uint
-    notification_emails:
-      - gachen@mozilla.com
-    record_in_processes:
-      - 'main'
-
 # The following section is for probes testing the Telemetry system. They will not be
 # submitted in pings and are only used for testing.
 telemetry.test:
   unsigned_int_kind:
     bug_numbers:
       - 1276190
     description: >
       This is a test uint type with a really long description, maybe spanning even multiple