summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2017-02-27 14:52:08 -0500
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2017-02-27 14:52:08 -0500
commit578e927641477bfbd032adbe7717fda45c0cc0ea (patch)
tree6417a1e5423f7a63af8c89c953049b658723a0e4 /indra
parent976b4f91ef3cfd36c0007d5b10d71c92b8bb3c44 (diff)
SL-409 - viewer asset stats updates to distinguish http and udp fetches
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llviewerassetstats.cpp191
-rw-r--r--indra/newview/llviewerassetstats.h16
-rw-r--r--indra/newview/llviewerassetstorage.cpp29
-rw-r--r--indra/newview/tests/llviewerassetstats_test.cpp13
4 files changed, 142 insertions, 107 deletions
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
index 54ac29723f..012da212a9 100644
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -90,90 +90,32 @@ namespace LLViewerAssetStatsFF
// - wearables (clothing, bodyparts) which directly affect
// user experiences when they log in
// - sounds
- // - gestures
+ // - gestures, including animations
// - everything else.
//
- llassert_always(50 == LLViewerAssetType::AT_COUNT);
- // Multiple asset definitions are floating around so this requires some
- // maintenance and attention.
- static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] =
- {
- EVACTextureTempHTTPGet, // (0) AT_TEXTURE
- EVACSoundUDPGet, // AT_SOUND
- EVACOtherGet, // AT_CALLINGCARD
- EVACOtherGet, // AT_LANDMARK
- EVACOtherGet, // AT_SCRIPT
- EVACWearableUDPGet, // AT_CLOTHING
- EVACOtherGet, // AT_OBJECT
- EVACOtherGet, // AT_NOTECARD
- EVACOtherGet, // AT_CATEGORY
- EVACOtherGet, // AT_ROOT_CATEGORY
- EVACOtherGet, // (10) AT_LSL_TEXT
- EVACOtherGet, // AT_LSL_BYTECODE
- EVACOtherGet, // AT_TEXTURE_TGA
- EVACWearableUDPGet, // AT_BODYPART
- EVACOtherGet, // AT_TRASH
- EVACOtherGet, // AT_SNAPSHOT_CATEGORY
- EVACOtherGet, // AT_LOST_AND_FOUND
- EVACSoundUDPGet, // AT_SOUND_WAV
- EVACOtherGet, // AT_IMAGE_TGA
- EVACOtherGet, // AT_IMAGE_JPEG
- EVACGestureUDPGet, // (20) AT_ANIMATION
- EVACGestureUDPGet, // AT_GESTURE
- EVACOtherGet, // AT_SIMSTATE
- EVACOtherGet, // AT_FAVORITE
- EVACOtherGet, // AT_LINK
- EVACOtherGet, // AT_LINK_FOLDER
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, // (30)
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, // (40)
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, //
- EVACOtherGet, // AT_MESH
- // (50)
- };
-
- if (at < 0 || at >= LLViewerAssetType::AT_COUNT)
- {
- return EVACOtherGet;
- }
- EViewerAssetCategories ret(asset_to_bin_map[at]);
- if (EVACTextureTempHTTPGet == ret)
- {
- // Indexed with [is_temp][with_http]
- static const EViewerAssetCategories texture_bin_map[2][2] =
- {
- {
- EVACTextureNonTempUDPGet,
- EVACTextureNonTempHTTPGet,
- },
- {
- EVACTextureTempUDPGet,
- EVACTextureTempHTTPGet,
- }
- };
-
- ret = texture_bin_map[is_temp][with_http];
- }
+ EViewerAssetCategories ret(EVACOtherGet);
+ switch (at)
+ {
+ case LLAssetType::AT_TEXTURE:
+ if (is_temp)
+ ret = with_http ? EVACTextureTempHTTPGet : EVACTextureTempUDPGet;
+ else
+ ret = with_http ? EVACTextureNonTempHTTPGet : EVACTextureNonTempUDPGet;
+ break;
+ case LLAssetType::AT_SOUND:
+ case LLAssetType::AT_SOUND_WAV:
+ ret = with_http ? EVACSoundHTTPGet : EVACSoundUDPGet;
+ break;
+ case LLAssetType::AT_CLOTHING:
+ case LLAssetType::AT_BODYPART:
+ ret = with_http ? EVACWearableHTTPGet : EVACWearableUDPGet;
+ break;
+ case LLAssetType::AT_ANIMATION:
+ case LLAssetType::AT_GESTURE:
+ ret = with_http ? EVACGestureHTTPGet : EVACGestureUDPGet;
+ break;
+ }
return ret;
}
@@ -185,12 +127,18 @@ namespace LLViewerAssetStatsFF
"Number of texture asset http requests enqueued"),
sEnqueueAssetRequestsNonTempTextureUDP ("enqueuedassetrequestsnontemptextureudp",
"Number of texture asset udp requests enqueued"),
+ sEnqueuedAssetRequestsWearableHTTP ("enqueuedassetrequestswearablehttp",
+ "Number of wearable asset http requests enqueued"),
sEnqueuedAssetRequestsWearableUdp ("enqueuedassetrequestswearableudp",
- "Number of wearable asset requests enqueued"),
+ "Number of wearable asset udp requests enqueued"),
+ sEnqueuedAssetRequestsSoundHTTP ("enqueuedassetrequestssoundhttp",
+ "Number of sound asset http requests enqueued"),
sEnqueuedAssetRequestsSoundUdp ("enqueuedassetrequestssoundudp",
- "Number of sound asset requests enqueued"),
+ "Number of sound asset udp requests enqueued"),
+ sEnqueuedAssetRequestsGestureHTTP ("enqueuedassetrequestsgesturehttp",
+ "Number of gesture asset http requests enqueued"),
sEnqueuedAssetRequestsGestureUdp ("enqueuedassetrequestsgestureudp",
- "Number of gesture asset requests enqueued"),
+ "Number of gesture asset udp requests enqueued"),
sEnqueuedAssetRequestsOther ("enqueuedassetrequestsother",
"Number of other asset requests enqueued");
@@ -199,8 +147,11 @@ namespace LLViewerAssetStatsFF
&sEnqueueAssetRequestsTempTextureUDP,
&sEnqueueAssetRequestsNonTempTextureHTTP,
&sEnqueueAssetRequestsNonTempTextureUDP,
+ &sEnqueuedAssetRequestsWearableHTTP,
&sEnqueuedAssetRequestsWearableUdp,
+ &sEnqueuedAssetRequestsSoundHTTP,
&sEnqueuedAssetRequestsSoundUdp,
+ &sEnqueuedAssetRequestsGestureHTTP,
&sEnqueuedAssetRequestsGestureUdp,
&sEnqueuedAssetRequestsOther
};
@@ -213,12 +164,18 @@ namespace LLViewerAssetStatsFF
"Number of texture asset http requests dequeued"),
sDequeueAssetRequestsNonTempTextureUDP ("dequeuedassetrequestsnontemptextureudp",
"Number of texture asset udp requests dequeued"),
+ sDequeuedAssetRequestsWearableHTTP ("dequeuedassetrequestswearablehttp",
+ "Number of wearable asset http requests dequeued"),
sDequeuedAssetRequestsWearableUdp ("dequeuedassetrequestswearableudp",
- "Number of wearable asset requests dequeued"),
+ "Number of wearable asset udp requests dequeued"),
+ sDequeuedAssetRequestsSoundHTTP ("dequeuedassetrequestssoundhttp",
+ "Number of sound asset http requests dequeued"),
sDequeuedAssetRequestsSoundUdp ("dequeuedassetrequestssoundudp",
- "Number of sound asset requests dequeued"),
+ "Number of sound asset udp requests dequeued"),
+ sDequeuedAssetRequestsGestureHTTP ("dequeuedassetrequestsgesturehttp",
+ "Number of gesture asset http requests dequeued"),
sDequeuedAssetRequestsGestureUdp ("dequeuedassetrequestsgestureudp",
- "Number of gesture asset requests dequeued"),
+ "Number of gesture asset udp requests dequeued"),
sDequeuedAssetRequestsOther ("dequeuedassetrequestsother",
"Number of other asset requests dequeued");
@@ -227,8 +184,11 @@ namespace LLViewerAssetStatsFF
&sDequeueAssetRequestsTempTextureUDP,
&sDequeueAssetRequestsNonTempTextureHTTP,
&sDequeueAssetRequestsNonTempTextureUDP,
+ &sDequeuedAssetRequestsWearableHTTP,
&sDequeuedAssetRequestsWearableUdp,
+ &sDequeuedAssetRequestsSoundHTTP,
&sDequeuedAssetRequestsSoundUdp,
+ &sDequeuedAssetRequestsGestureHTTP,
&sDequeuedAssetRequestsGestureUdp,
&sDequeuedAssetRequestsOther
};
@@ -241,12 +201,18 @@ namespace LLViewerAssetStatsFF
"Time spent responding to texture asset http requests"),
sResponseAssetRequestsNonTempTextureUDP ("assetresponsetimesnontemptextureudp",
"Time spent responding to texture asset udp requests"),
+ sResponsedAssetRequestsWearableHTTP ("assetresponsetimeswearablehttp",
+ "Time spent responding to wearable asset http requests"),
sResponsedAssetRequestsWearableUdp ("assetresponsetimeswearableudp",
- "Time spent responding to wearable asset requests"),
+ "Time spent responding to wearable asset udp requests"),
+ sResponsedAssetRequestsSoundHTTP ("assetresponsetimessounduhttp",
+ "Time spent responding to sound asset http requests"),
sResponsedAssetRequestsSoundUdp ("assetresponsetimessoundudp",
- "Time spent responding to sound asset requests"),
+ "Time spent responding to sound asset udp requests"),
+ sResponsedAssetRequestsGestureHTTP ("assetresponsetimesgesturehttp",
+ "Time spent responding to gesture asset http requests"),
sResponsedAssetRequestsGestureUdp ("assetresponsetimesgestureudp",
- "Time spent responding to gesture asset requests"),
+ "Time spent responding to gesture asset udp requests"),
sResponsedAssetRequestsOther ("assetresponsetimesother",
"Time spent responding to other asset requests");
@@ -255,8 +221,11 @@ namespace LLViewerAssetStatsFF
&sResponseAssetRequestsTempTextureUDP,
&sResponseAssetRequestsNonTempTextureHTTP,
&sResponseAssetRequestsNonTempTextureUDP,
+ &sResponsedAssetRequestsWearableHTTP,
&sResponsedAssetRequestsWearableUdp,
+ &sResponsedAssetRequestsSoundHTTP,
&sResponsedAssetRequestsSoundUdp,
+ &sResponsedAssetRequestsGestureHTTP,
&sResponsedAssetRequestsGestureUdp,
&sResponsedAssetRequestsOther
};
@@ -416,6 +385,19 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
}
if (!compact_output
+ || rec.getSum(*sEnqueued[EVACWearableHTTPGet])
+ || rec.getSum(*sDequeued[EVACWearableHTTPGet])
+ || rec.getSum(*sResponse[EVACWearableHTTPGet]).value())
+ {
+ r.get_wearable_http .enqueued((S32)rec.getSum(*sEnqueued[EVACWearableHTTPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACWearableHTTPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACWearableHTTPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACWearableHTTPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACWearableHTTPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACWearableHTTPGet]).value());
+ }
+
+ if (!compact_output
|| rec.getSum(*sEnqueued[EVACWearableUDPGet])
|| rec.getSum(*sDequeued[EVACWearableUDPGet])
|| rec.getSum(*sResponse[EVACWearableUDPGet]).value())
@@ -429,6 +411,19 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
}
if (!compact_output
+ || rec.getSum(*sEnqueued[EVACSoundHTTPGet])
+ || rec.getSum(*sDequeued[EVACSoundHTTPGet])
+ || rec.getSum(*sResponse[EVACSoundHTTPGet]).value())
+ {
+ r.get_sound_http.enqueued((S32)rec.getSum(*sEnqueued[EVACSoundHTTPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACSoundHTTPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACSoundHTTPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACSoundHTTPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACSoundHTTPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACSoundHTTPGet]).value());
+ }
+
+ if (!compact_output
|| rec.getSum(*sEnqueued[EVACSoundUDPGet])
|| rec.getSum(*sDequeued[EVACSoundUDPGet])
|| rec.getSum(*sResponse[EVACSoundUDPGet]).value())
@@ -442,6 +437,19 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
}
if (!compact_output
+ || rec.getSum(*sEnqueued[EVACGestureHTTPGet])
+ || rec.getSum(*sDequeued[EVACGestureHTTPGet])
+ || rec.getSum(*sResponse[EVACGestureHTTPGet]).value())
+ {
+ r.get_gesture_http .enqueued((S32)rec.getSum(*sEnqueued[EVACGestureHTTPGet]))
+ .dequeued((S32)rec.getSum(*sDequeued[EVACGestureHTTPGet]))
+ .resp_count((S32)rec.getSum(*sResponse[EVACGestureHTTPGet]).value())
+ .resp_min(rec.getMin(*sResponse[EVACGestureHTTPGet]).value())
+ .resp_max(rec.getMax(*sResponse[EVACGestureHTTPGet]).value())
+ .resp_mean(rec.getMean(*sResponse[EVACGestureHTTPGet]).value());
+ }
+
+ if (!compact_output
|| rec.getSum(*sEnqueued[EVACGestureUDPGet])
|| rec.getSum(*sDequeued[EVACGestureUDPGet])
|| rec.getSum(*sResponse[EVACGestureUDPGet]).value())
@@ -576,8 +584,11 @@ LLViewerAssetStats::RegionStats::RegionStats()
get_texture_temp_udp("get_texture_temp_udp"),
get_texture_non_temp_http("get_texture_non_temp_http"),
get_texture_non_temp_udp("get_texture_non_temp_udp"),
+ get_wearable_http("get_wearable_http"),
get_wearable_udp("get_wearable_udp"),
+ get_sound_http("get_sound_http"),
get_sound_udp("get_sound_udp"),
+ get_gesture_http("get_gesture_http"),
get_gesture_udp("get_gesture_udp"),
get_other("get_other"),
fps("fps"),
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
index 9d425c82fc..ddddf7883b 100644
--- a/indra/newview/llviewerassetstats.h
+++ b/indra/newview/llviewerassetstats.h
@@ -104,7 +104,7 @@ public:
};
struct FPSStats : public LLInitParam::Block<FPSStats>
- {
+ {
Mandatory<S32> count;
Mandatory<F64> min,
max,
@@ -113,13 +113,16 @@ public:
};
struct RegionStats : public LLInitParam::Block<RegionStats>
- {
+ {
Optional<AssetRequestType> get_texture_temp_http,
get_texture_temp_udp,
get_texture_non_temp_http,
get_texture_non_temp_udp,
+ get_wearable_http,
get_wearable_udp,
+ get_sound_http,
get_sound_udp,
+ get_gesture_http,
get_gesture_udp,
get_other;
Optional<FPSStats> fps;
@@ -211,9 +214,12 @@ namespace LLViewerAssetStatsFF
EVACTextureTempUDPGet, //< Texture GETs - temp/baked, UDP
EVACTextureNonTempHTTPGet, //< Texture GETs - perm, HTTP
EVACTextureNonTempUDPGet, //< Texture GETs - perm, UDP
- EVACWearableUDPGet, //< Wearable GETs
- EVACSoundUDPGet, //< Sound GETs
- EVACGestureUDPGet, //< Gesture GETs
+ EVACWearableHTTPGet, //< Wearable GETs HTTP
+ EVACWearableUDPGet, //< Wearable GETs UDP
+ EVACSoundHTTPGet, //< Sound GETs HTTP
+ EVACSoundUDPGet, //< Sound GETs UDP
+ EVACGestureHTTPGet, //< Gesture GETs HTTP
+ EVACGestureUDPGet, //< Gesture GETs UDP
EVACOtherGet, //< Other GETs
EVACCount // Must be last
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 3bb2b531dc..347810e169 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -56,9 +56,10 @@
class LLViewerAssetRequest : public LLAssetRequest
{
public:
- LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type)
+ LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type, bool with_http)
: LLAssetRequest(uuid, type),
- mMetricsStartTime(0)
+ mMetricsStartTime(0),
+ mWithHTTP(with_http)
{
}
@@ -78,8 +79,8 @@ protected:
{
// Okay, it appears this request was used for useful things. Record
// the expected dequeue and duration of request processing.
- LLViewerAssetStatsFF::record_dequeue(mType, false, false);
- LLViewerAssetStatsFF::record_response(mType, false, false,
+ LLViewerAssetStatsFF::record_dequeue(mType, mWithHTTP, false);
+ LLViewerAssetStatsFF::record_response(mType, mWithHTTP, false,
(LLViewerAssetStatsFF::get_timestamp()
- mMetricsStartTime));
mMetricsStartTime = (U32Seconds)0;
@@ -88,6 +89,7 @@ protected:
public:
LLViewerAssetStats::duration_t mMetricsStartTime;
+ bool mWithHTTP;
};
///----------------------------------------------------------------------------
@@ -369,7 +371,8 @@ void LLViewerAssetStorage::queueRequestUDP(
if (mUpstreamHost.isOk())
{
// stash the callback info so we can find it after we get the response message
- LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype);
+ bool with_http = false;
+ LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype, with_http);
req->mDownCallback = callback;
req->mUserData = user_data;
req->mIsPriority = is_priority;
@@ -398,7 +401,9 @@ void LLViewerAssetStorage::queueRequestUDP(
LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);
ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f));
- LLViewerAssetStatsFF::record_enqueue(atype, false, false);
+ bool with_http = false;
+ bool is_temp = false;
+ LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
}
}
else
@@ -432,7 +437,8 @@ void LLViewerAssetStorage::queueRequestHttp(
{
LL_DEBUGS("ViewerAsset") << "Will fetch via ViewerAsset cap " << cap_url << LL_ENDL;
- LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype);
+ bool with_http = true;
+ LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype, with_http);
req->mDownCallback = callback;
req->mUserData = user_data;
req->mIsPriority = is_priority;
@@ -447,7 +453,9 @@ void LLViewerAssetStorage::queueRequestHttp(
// This is the same as the current UDP logic - don't re-request a duplicate.
if (!duplicate)
{
- LLViewerAssetStatsFF::record_enqueue(atype, false, false);
+ bool with_http = true;
+ bool is_temp = false;
+ LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
LLCoros::instance().launch("LLViewerAssetStorage::assetRequestCoro",
boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, uuid, atype, callback, user_data));
@@ -481,9 +489,9 @@ void LLViewerAssetStorage::assetRequestCoro(
}
else
{
- LL_DEBUGS("ViewerAsset") << "request succeeded" << LL_ENDL;
+ LL_DEBUGS("ViewerAsset") << "request succeeded, url " << url << LL_ENDL;
- LL_DEBUGS("ViewerAsset") << "result: " << ll_pretty_print_sd(httpResults) << LL_ENDL;
+ // LL_DEBUGS("ViewerAsset") << "result: " << ll_pretty_print_sd(httpResults) << LL_ENDL;
const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
@@ -508,6 +516,7 @@ void LLViewerAssetStorage::assetRequestCoro(
else
{
// TODO asset-http: handle invalid size case
+ LL_ERRS() << "bad size" << LL_ENDL;
}
// Clean up pending downloads and trigger callbacks
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index a08e32cb49..ed3051893e 100644
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -76,8 +76,11 @@ static const char * all_keys[] =
"get_texture_temp_udp",
"get_texture_non_temp_http",
"get_texture_non_temp_udp",
+ "get_wearable_http",
"get_wearable_udp",
+ "get_sound_http",
"get_sound_udp",
+ "get_gesture_http",
"get_gesture_udp"
};
@@ -88,8 +91,11 @@ static const char * resp_keys[] =
"get_texture_temp_udp",
"get_texture_non_temp_http",
"get_texture_non_temp_udp",
+ "get_wearable_http",
"get_wearable_udp",
+ "get_sound_http",
"get_sound_udp",
+ "get_gesture_http",
"get_gesture_udp"
};
@@ -540,8 +546,11 @@ namespace tut
ensure("sd[get_gesture_udp][enqueued] is 0", (0 == sd["get_gesture_udp"]["enqueued"].asInteger()));
ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
- ensure("sd[get_wearable_udp][enqueued] is 4", (4 == sd["get_wearable_udp"]["enqueued"].asInteger()));
- ensure("sd[get_wearable_udp][dequeued] is 4", (4 == sd["get_wearable_udp"]["dequeued"].asInteger()));
+ ensure("sd[get_wearable_http][enqueued] is 2", (2 == sd["get_wearable_http"]["enqueued"].asInteger()));
+ ensure("sd[get_wearable_http][dequeued] is 2", (2 == sd["get_wearable_http"]["dequeued"].asInteger()));
+
+ ensure("sd[get_wearable_udp][enqueued] is 2", (2 == sd["get_wearable_udp"]["enqueued"].asInteger()));
+ ensure("sd[get_wearable_udp][dequeued] is 2", (2 == sd["get_wearable_udp"]["dequeued"].asInteger()));
ensure("sd[get_other][enqueued] is 4", (4 == sd["get_other"]["enqueued"].asInteger()));
ensure("sd[get_other][dequeued] is 0", (0 == sd["get_other"]["dequeued"].asInteger()));