Skip to content

Commit

Permalink
Fix some problems with the entry store
Browse files Browse the repository at this point in the history
  • Loading branch information
LorenDB committed Dec 8, 2022
1 parent 4311c94 commit 7117365
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 51 deletions.
24 changes: 14 additions & 10 deletions src/DailyOverviewDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <QPushButton>
#include <QThread>

#include "Logger.h"
#include "TimeEntry.h"

class TimeTableItem : public QTableWidgetItem
Expand Down Expand Up @@ -138,7 +139,13 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointer<AbstractTimeServiceManag
}))
.toString(QStringLiteral("h:mm:ss"))));
};
auto updateData = [this, datePicker, forward, back, today, reset, updateTotalTime] {

auto totalTimeUpdater = new QTimer{this};
totalTimeUpdater->setInterval(1000);
totalTimeUpdater->callOnTimeout(updateTotalTime);
totalTimeUpdater->start();

auto updateData = [this, datePicker, forward, back, today, reset, updateTotalTime, totalTimeUpdater] {
auto todaysTime = m_entries->constSliceByDate(QDateTime{m_day, QTime{}}, m_day.endOfDay());

updateTotalTime();
Expand All @@ -157,6 +164,7 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointer<AbstractTimeServiceManag
for (const auto &t : todaysTime)
msecsByProject[t.project().id()] += t.start().msecsTo(t.end());
m_byProjectTable->clearContents();
m_byProjectTable->setRowCount(0);
m_byProjectTable->setRowCount(static_cast<int>(msecsByProject.count()));
int _i = 0;
for (const auto &key : msecsByProject.keys())
Expand All @@ -170,6 +178,7 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointer<AbstractTimeServiceManag
++_i;
}

m_loadingEntries->setVisible(false);
if (m_day == datePicker->maximumDate())
forward->setDisabled(true);
else
Expand All @@ -181,31 +190,26 @@ DailyOverviewDialog::DailyOverviewDialog(QSharedPointer<AbstractTimeServiceManag
datePicker->setEnabled(true);
today->setEnabled(true);
reset->setEnabled(true);
m_loadingEntries->setVisible(false);
totalTimeUpdater->start();
};
updateData();

auto totalTimeUpdater = new QTimer{this};
totalTimeUpdater->setInterval(1000);
totalTimeUpdater->callOnTimeout(updateTotalTime);
totalTimeUpdater->start();

connect(bb, &QDialogButtonBox::accepted, this, &QDialog::close);
connect(breakdown, &QComboBox::currentIndexChanged, this, setProperTimeTable);
connect(datePicker,
&QDateEdit::dateChanged,
this,
[this, updateData, forward, back, datePicker, today, reset](const QDate &d) {
[this, updateData, forward, back, datePicker, today, reset, totalTimeUpdater](const QDate &d) {
m_day = d;

totalTimeUpdater->stop();
forward->setDisabled(true);
back->setDisabled(true);
datePicker->setDisabled(true);
today->setDisabled(true);
reset->setDisabled(true);
m_loadingEntries->setVisible(true);

QThread::create([updateData] { updateData(); })->start();
QTimer::singleShot(0, [updateData] { updateData(); });
});
connect(back, &QPushButton::clicked, datePicker, [datePicker] { datePicker->setDate(datePicker->date().addDays(-1)); });
connect(
Expand Down
96 changes: 56 additions & 40 deletions src/TimeEntryStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,59 +60,75 @@ void TimeEntryStore::fetchMore()
if (m_isAtEnd)
return;

TimeLight::logs::app()->trace("TimeEntryStore::fetchMore() on thread {}: lock mutex", QThread::currentThreadId());
QMutexLocker _{&m_mutex};
auto moreEntries = m_user->getTimeEntries(m_nextPage++);
if (moreEntries.isEmpty())
m_isAtEnd = true;
else
if (m_mutex.tryLock())
{
beginInsertRows({}, m_store.size(), m_store.size() + moreEntries.size() - 1);
m_store.append(moreEntries);
endInsertRows();
TimeLight::logs::app()->trace("TimeEntryStore::fetchMore() on thread {}: lock mutex", QThread::currentThreadId());
auto moreEntries = m_user->getTimeEntries(m_nextPage++);
if (moreEntries.isEmpty())
m_isAtEnd = true;
else
{
beginInsertRows({}, m_store.size(), m_store.size() + moreEntries.size() - 1);
m_store.append(moreEntries);
endInsertRows();
}
m_mutex.unlock();
TimeLight::logs::app()->trace("TimeEntryStore::fetchMore() on thread {}: unlock mutex", QThread::currentThreadId());
}
TimeLight::logs::app()->trace("TimeEntryStore::fetchMore() on thread {}: unlock mutex", QThread::currentThreadId());
else
QTimer::singleShot(10, this, &TimeEntryStore::fetchMore);
}

void TimeEntryStore::clearStore()
{
TimeLight::logs::app()->trace("TimeEntryStore::clearStore() on thread {}: lock mutex", QThread::currentThreadId());
QMutexLocker _{&m_mutex};
beginResetModel();
m_store.clear();
endResetModel();
m_nextPage = m_user->manager()->paginationStartsAt();
m_isAtEnd = false;
TimeLight::logs::app()->trace("TimeEntryStore::clearStore() on thread {}: unlock mutex", QThread::currentThreadId());
if (m_mutex.tryLock())
{
TimeLight::logs::app()->trace("TimeEntryStore::clearStore() on thread {}: lock mutex", QThread::currentThreadId());
beginResetModel();
m_store.clear();
endResetModel();
m_nextPage = m_user->manager()->paginationStartsAt();
m_isAtEnd = false;
m_mutex.unlock();
TimeLight::logs::app()->trace("TimeEntryStore::clearStore() on thread {}: unlock mutex", QThread::currentThreadId());
}
else
QTimer::singleShot(10, this, &TimeEntryStore::clearStore);
}

void TimeEntryStore::insert(const TimeEntry &t)
{
TimeLight::logs::app()->trace("TimeEntryStore::insert() on thread {}: lock mutex", QThread::currentThreadId());
QMutexLocker _{&m_mutex};
if (auto it = std::find_if(static_begin(), static_end(), [&t](const auto &x) { return t.id() == x.id(); });
it != static_end())
*it = t;
else if (auto it = std::find_if(static_cbegin(), static_cend(), [&t](const auto &x) { return x.start() > t.start(); });
it != static_cend())
if (m_mutex.tryLock())
{
beginInsertRows({}, it.index(), it.index());
m_store.insert(it.index(), t);
endInsertRows();
}
else if (t.start() > m_store.first().start())
{
beginInsertRows({}, 0, 0);
m_store.prepend(t);
endInsertRows();
TimeLight::logs::app()->trace("TimeEntryStore::insert() on thread {}: lock mutex", QThread::currentThreadId());
if (auto it = std::find_if(static_begin(), static_end(), [&t](const auto &x) { return t.id() == x.id(); });
it != static_end())
*it = t;
else if (auto it =
std::find_if(static_cbegin(), static_cend(), [&t](const auto &x) { return x.start() > t.start(); });
it != static_cend())
{
beginInsertRows({}, it.index(), it.index());
m_store.insert(it.index(), t);
endInsertRows();
}
else if (m_store.size() > 0 && t.start() > m_store.first().start())
{
beginInsertRows({}, 0, 0);
m_store.prepend(t);
endInsertRows();
}
else
{
beginInsertRows({}, m_store.size(), m_store.size());
m_store.append(t);
endInsertRows();
}
m_mutex.unlock();
TimeLight::logs::app()->trace("TimeEntryStore::insert() on thread {}: unlock mutex", QThread::currentThreadId());
}
else
{
beginInsertRows({}, m_store.size(), m_store.size());
m_store.append(t);
endInsertRows();
}
TimeLight::logs::app()->trace("TimeEntryStore::insert() on thread {}: unlock mutex", QThread::currentThreadId());
QTimer::singleShot(10, std::bind(&TimeEntryStore::insert, this, std::move(t)));
}

RangeSlice<TimeEntryStore::iterator> TimeEntryStore::sliceByDate(const QDateTime &oldest, const QDateTime &newest)
Expand Down
2 changes: 1 addition & 1 deletion src/TrayIcons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ void TrayIcons::updateTrayIcons()
m_currentRunningJob = runningEntry;

// This request is performed in another thread to minimize chances of lock races
QThread::create([this, runningEntry] { m_timeEntries->insert(*runningEntry); })->start();
m_timeEntries->insert(*runningEntry);

if (Settings::instance()->useSeparateBreakTime() &&
runningEntry->project().id() == Settings::instance()->breakTimeId())
Expand Down

0 comments on commit 7117365

Please sign in to comment.