Skip to content

Commit 0face01

Browse files
committed
Merge remote-tracking branch 'origin/candidate-9.12.x' into candidate-9.14.x
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
2 parents e684fbb + 2a4eef9 commit 0face01

File tree

2 files changed

+42
-43
lines changed

2 files changed

+42
-43
lines changed

dali/base/dasds.cpp

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,15 +1119,15 @@ class CTransactionItem : public CSimpleInterface
11191119

11201120
static constexpr unsigned defaultSaveThresholdSecs = 0; // disabled
11211121
static constexpr unsigned defaultDeltaSaveTransactionThreshold = 0; // disabled
1122-
static constexpr unsigned defaultDeltaMemMaxMB = 10;
1122+
static constexpr unsigned defaultDeltaMemMaxMB = 64; // 64MB a reasonably large default, to cope with large blobs being committed
11231123
static constexpr unsigned defaultDeltaTransactionQueueLimit = 10000;
11241124
class CDeltaWriter : implements IThreaded
11251125
{
11261126
IStoreHelper *iStoreHelper = nullptr;
11271127
StringBuffer dataPath;
11281128
StringBuffer backupPath;
11291129
unsigned transactionQueueLimit = defaultDeltaTransactionQueueLimit; // absolute limit, will block if this far behind
1130-
memsize_t transactionMaxMem = defaultDeltaMemMaxMB * 0x100000; // 10MB
1130+
memsize_t transactionMaxMem = defaultDeltaMemMaxMB * 0x100000;
11311131
unsigned totalQueueLimitHits = 0;
11321132
unsigned saveThresholdSecs = 0;
11331133
cycle_t lastSaveTime = 0;
@@ -1414,40 +1414,34 @@ class CDeltaWriter : implements IThreaded
14141414
// keep going whilst there's things pending
14151415
while (true)
14161416
{
1417-
CLeavableCriticalBlock b(pendingCrit);
1418-
std::queue<Owned<CTransactionItem>> todo = std::move(pending);
1419-
if (0 == todo.size())
1417+
// NB: ensure consistent lock ordering of blockedSaveCrit and pendingCrit
1418+
CHECKEDCRITICALBLOCK(blockedSaveCrit, fakeCritTimeout); // because if Dali is saving state (::blockingSave), it will clear pending
1419+
std::queue<Owned<CTransactionItem>> todo;
14201420
{
1421-
if (writeRequested)
1421+
CriticalBlock b(pendingCrit);
1422+
todo = std::move(pending);
1423+
if (0 == todo.size())
14221424
{
1423-
// NB: if here, implies someone signalled via requestAsyncWrite()
1425+
if (writeRequested)
1426+
{
1427+
// NB: if here, implies someone signalled via requestAsyncWrite()
14241428

1425-
// if reason we're here is because sem timedout, consume the signal that was sent
1426-
if (semTimedout)
1427-
pendingTransactionsSem.wait();
1429+
// if reason we're here is because sem timedout, consume the signal that was sent
1430+
if (semTimedout)
1431+
pendingTransactionsSem.wait();
14281432

1429-
writeRequested = false;
1430-
if (signalWhenAllWritten) // can only be true if writeRequested was true
1431-
{
1432-
signalWhenAllWritten = false;
1433-
allWrittenSem.signal();
1433+
writeRequested = false;
1434+
if (signalWhenAllWritten) // can only be true if writeRequested was true
1435+
{
1436+
signalWhenAllWritten = false;
1437+
allWrittenSem.signal();
1438+
}
14341439
}
1440+
break;
14351441
}
1436-
break;
1442+
pendingSz = 0;
14371443
}
1438-
pendingSz = 0;
14391444

1440-
b.leave(); // NB: addToQueue could add to pending between here and regaining lock below
1441-
// NB: ensure consistent lock ordering of blockedSaveCrit and pendingCrit
1442-
CHECKEDCRITICALBLOCK(blockedSaveCrit, fakeCritTimeout); // because if Dali is saving state (::blockingSave), it will clear pending
1443-
b.enter();
1444-
// check if new items added in window above
1445-
while (pending.size())
1446-
{
1447-
todo.push(std::move(pending.front()));
1448-
pending.pop();
1449-
}
1450-
b.leave();
14511445
// Because blockedSaveCrit is held, it will also block 'synchronous save' (see addToQueue)
14521446
// i.e. if stuck here, the transactions will start building up, and trigger a 'Forced synchronous save',
14531447
// which will in turn block. This must complete!
@@ -2266,14 +2260,15 @@ void CBinaryFileExternal::write(const char *name, IPropertyTree &tree)
22662260
void CDeltaWriter::addToQueue(CTransactionItem *item)
22672261
{
22682262
bool needsSyncSave = false;
2263+
size_t items;
22692264
{
22702265
CriticalBlock b(pendingCrit);
22712266
pending.push(item);
22722267
// add actual size for externals, and nominal '100 byte' value for delta transactions
22732268
// it will act. as a rough guide to appoaching size threshold. It is not worth
22742269
// synchronously preparing and serializing here (which will be done asynchronously later)
22752270
pendingSz += (CTransactionItem::f_addext == item->type) ? item->ext.dataLength : 100;
2276-
size_t items = pending.size();
2271+
items = pending.size();
22772272
if ((pendingSz < transactionMaxMem) && (items < transactionQueueLimit))
22782273
{
22792274
if (lastSaveTime && ((get_cycles_now() - lastSaveTime) < thresholdDuration))
@@ -2293,12 +2288,12 @@ void CDeltaWriter::addToQueue(CTransactionItem *item)
22932288
++totalQueueLimitHits;
22942289
// force a synchronous save
22952290
CCycleTimer timer;
2296-
PROGLOG("Forcing synchronous save of %u transactions (pendingSz=%zu)", (unsigned)pending.size(), pendingSz);
2291+
PROGLOG("Forcing synchronous save of %u transactions (pendingSz=%zu)", (unsigned)items, pendingSz);
22972292

22982293
// NB: ensure consistent lock ordering of blockedSaveCrit and pendingCrit
22992294
CHECKEDCRITICALBLOCK(blockedSaveCrit, fakeCritTimeout); // because if Dali is saving state (::blockingSave), it will clear pending
23002295
CriticalBlock b(pendingCrit);
2301-
size_t items = pending.size();
2296+
items = pending.size();
23022297
// NB: items could be 0. It's possible that the delta writer has caught up and flushed pending already
23032298
if (items && save(pending)) // if temporarily blocked, continue, meaning queue limit will overrun a bit (blocking window is short)
23042299
{

esp/src/tests/v9-workunits.spec.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,8 @@ test.describe("V9 Workunits", () => {
2727
];
2828

2929
for (const column of expectedColumns) {
30-
if (column === "Cluster") {
31-
await expect(page.getByText(column, { exact: true })).toBeVisible();
32-
} else {
33-
await expect(page.getByText(column)).toBeVisible();
34-
}
30+
// Use column header selector with exact match to avoid ambiguity
31+
await expect(page.getByRole("columnheader", { name: column, exact: true })).toBeVisible();
3532
}
3633

3734
for (const column of costColumns) {
@@ -54,21 +51,25 @@ test.describe("V9 Workunits", () => {
5451
await page.getByRole("menuitem", { name: "Filter" }).click();
5552
await page.getByRole("textbox", { name: "Job Name" }).fill("global.setup.ts");
5653
await page.getByRole("button", { name: "Apply" }).click();
57-
expect(await page.locator(".ms-DetailsRow")).not.toHaveCount(0);
54+
55+
// Wait for filter to apply and results to load
56+
await page.waitForTimeout(1000);
57+
await expect(page.locator(".ms-DetailsRow")).not.toHaveCount(0, { timeout: 10000 });
58+
5859
await page.getByRole("menuitem", { name: "Filter" }).click();
5960
});
6061

6162
test("Should allow protecting and unprotecting a workunit and reflect lock status", async ({ page, browserName }) => {
62-
expect(await page.locator(".ms-DetailsRow")).not.toHaveCount(0);
63+
await expect(page.locator(".ms-DetailsRow")).not.toHaveCount(0);
6364
await page.locator(".ms-DetailsRow").first().locator(".ms-DetailsRow-check").click();
64-
expect(await page.locator(".ms-DetailsRow.is-selected")).toHaveCount(1);
65+
await expect(page.locator(".ms-DetailsRow.is-selected")).toHaveCount(1);
6566
if (browserName === "chromium") {
6667
await page.getByRole("menuitem", { name: "Protect", exact: true }).click();
67-
expect(await page.locator(".ms-DetailsRow").first().locator("[data-icon-name=\"LockSolid\"]")).toBeVisible();
68+
await expect(page.locator(".ms-DetailsRow").first().locator("[data-icon-name=\"LockSolid\"]")).toBeVisible();
6869
await page.locator(".ms-DetailsRow").first().locator(".ms-DetailsRow-check").click();
69-
expect(await page.locator(".ms-DetailsRow.is-selected")).toHaveCount(1);
70+
await expect(page.locator(".ms-DetailsRow.is-selected")).toHaveCount(1);
7071
await page.getByRole("menuitem", { name: "Unprotect" }).click();
71-
expect(await page.locator(".ms-DetailsRow").first().locator("[data-icon-name=\"LockSolid\"]")).toHaveCount(0);
72+
await expect(page.locator(".ms-DetailsRow").first().locator("[data-icon-name=\"LockSolid\"]")).toHaveCount(0);
7273
}
7374
});
7475

@@ -78,7 +79,10 @@ test.describe("V9 Workunits", () => {
7879
expect(await page.locator(".ms-DetailsRow.is-selected")).toHaveCount(1);
7980
if (browserName === "chromium") {
8081
await page.getByRole("menuitem", { name: "Set To Failed", exact: true }).click();
81-
expect(await page.locator(".ms-DetailsRow").first()).toContainText("failed");
82+
83+
// Wait for the action to complete and UI to update
84+
await page.waitForTimeout(1000);
85+
await expect(page.locator(".ms-DetailsRow").first()).toContainText("failed", { timeout: 10000 });
8286
}
8387
});
8488

0 commit comments

Comments
 (0)