Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7547491
Implement write-locking (#162)
sjperkins Aug 12, 2025
aa7d08e
Update tbump.toml version regex to support pre-releases
sjperkins Aug 12, 2025
aad400c
Bump to 0.4.0-alpha.1
sjperkins Aug 12, 2025
4828982
Write locking improvements (#166)
sjperkins Aug 25, 2025
cd0e45b
Bump pypa/cibuildwheel from 3.1.1 to 3.1.3 (#163)
dependabot[bot] Aug 4, 2025
b0feb24
Bump actions/download-artifact from 4 to 5 (#164)
dependabot[bot] Aug 11, 2025
477f14d
Bump actions/checkout from 4 to 5 (#167)
dependabot[bot] Aug 18, 2025
e55ecfe
Bump pypa/cibuildwheel from 3.1.3 to 3.1.4 (#168)
dependabot[bot] Aug 25, 2025
fc794c7
Bump to 0.4.0-alpha.2
sjperkins Aug 25, 2025
80bfa7b
Merge branch 'main' into 0.4.0-dev
sjperkins Sep 17, 2025
c924006
Remove CIBW env cruft left over from the merge
sjperkins Sep 18, 2025
4f568f6
Bump to 0.4.0-alpha.3
sjperkins Sep 18, 2025
2042787
Merge branch 'main' into 0.4.0-dev
sjperkins Feb 11, 2026
0993190
Merge branch 'main' into 0.4.0-dev
sjperkins Feb 27, 2026
b36215f
Merge branch 'main' into 0.4.0-dev
sjperkins Mar 2, 2026
5ce1fe3
Merge branch 'main' into 0.4.0-dev
sjperkins Mar 2, 2026
9f5056b
Bump to 0.4.0-alpha.4
sjperkins Mar 2, 2026
723b69e
Merge branch 'main' into 0.4.0-dev
sjperkins Jun 12, 2026
3a2b0cb
Merge branch 'main' into 0.4.0-dev
sjperkins Jun 17, 2026
8139282
Bump to 0.4.0-alpha.5
sjperkins Jun 17, 2026
57fbbfc
IsolatedTableProxy improvements
sjperkins Jun 18, 2026
1dc6f18
Coordinate in-process table locks under user locking
sjperkins Jun 19, 2026
71acb38
Strict coercion to user locking
sjperkins Jun 19, 2026
c7958ae
Add interprocess locking tests
sjperkins Jun 19, 2026
f9e8088
.gitignore wheelhouse
sjperkins Jun 19, 2026
d3e4255
Bump to 0.4.0-alpha.6
sjperkins Jun 19, 2026
77cdc44
Merge main (casacore 3.8.1) into 0.4.0-dev (#219)
sjperkins Jul 1, 2026
f601893
Merge branch 'main' into 0.4.0-dev
sjperkins Jul 1, 2026
e20bd40
Bump to 0.4.0-alpha.7
sjperkins Jul 2, 2026
0b45b14
Merge branch 'main' into 0.4.0-dev
sjperkins Jul 22, 2026
0d3bd52
Merge branch 'main' into 0.4.0-dev
sjperkins Jul 22, 2026
e9ab55e
Bump to 0.4.0-alpha.8
sjperkins Jul 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,5 @@ pyrightconfig.json

# Casa tables
*.table

wheelhouse/*
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ History

0.5.3 (1-07-2026)
------------------
* Implement write-locking (:pr:`162`)
* Upgrade to casacore 3.8.1 (:pr:`218`)
* Remove extraneous whitespace in casacore patch (:pr:`215`)
* Introduce ``pytest != 9.1.0`` version restriction (:pr:`214`)
Expand Down
4 changes: 1 addition & 3 deletions cpp/arcae/configuration.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ using ::arrow::Status;

namespace arcae {

Status SafeMultiThreadedWrites() {
return Status::NotImplemented("Safe Multi-threaded write support");
}
Status SafeMultiThreadedWrites() { return Status::OK(); }

Result<std::string> Configuration::Get(const std::string& key) const {
if (auto it = kvmap_.find(key); it != kvmap_.end()) {
Expand Down
26 changes: 26 additions & 0 deletions cpp/arcae/finally.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef ARCAE_FINALLY_H
#define ARCAE_FINALLY_H

#include <utility>

namespace arcae {
namespace detail {

template <typename Fn>
struct Finally {
Fn fn;
bool enabled;
~Finally() {
if (enabled) fn();
}
};

template <typename Fn>
auto finally(Fn&& fn) {
return Finally<Fn>{std::forward<Fn>(fn), true};
}

} // namespace detail
} // namespace arcae

#endif // #define ARCAE_FINALLY_H
59 changes: 46 additions & 13 deletions cpp/arcae/isolated_table_proxy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,60 @@ const std::shared_ptr<ThreadPool>& IsolatedTableProxy::GetPool(
return proxy_pools_[instance].io_pool_;
}

std::shared_ptr<IsolatedTableProxy> IsolatedTableProxy::SpawnWriter() {
// Create an IsolatedTableProxy that serialises writes to a single
// table instance (and thread).
// A custom deleter that releases resources (proxies and pools)
// that are actually managed by the parent ITP
std::shared_ptr<IsolatedTableProxy> itp(new IsolatedTableProxy(), [](auto* p) {
p->proxy_pools_.clear();
p->dependencies_.clear();
p->is_closed_ = true;
delete p;
});
itp->dependencies_.emplace_back(shared_from_this());
// Using the first instance means that writes can still work after
// non-syncable operations like AddColumns
auto instance = 0; // GetInstance();
itp->proxy_pools_.push_back(proxy_pools_[instance]);
itp->is_closed_ = false;
return itp;
}

Status IsolatedTableProxy::CheckClosed() const {
if (!is_closed_) return Status::OK();
return Status::Invalid("TableProxy is closed");
}

Result<bool> IsolatedTableProxy::Close() {
if (!is_closed_) {
std::shared_ptr<void> defer_close(nullptr, [this](...) { this->is_closed_ = true; });
std::vector<Future<bool>> results;
results.reserve(proxy_pools_.size());
for (auto& [proxy, pool] : proxy_pools_) {
results.push_back(arrow::DeferNotOk(pool->Submit([tp = proxy]() {
if (is_closed_) return false;
// Mark closed on scope exit, regardless of how the close tasks fare.
std::shared_ptr<void> defer_close(nullptr, [this](...) { this->is_closed_ = true; });
std::vector<Future<bool>> results;
results.reserve(proxy_pools_.size());
for (auto& [proxy, pool] : proxy_pools_) {
results.push_back(arrow::DeferNotOk(pool->Submit([tp = proxy]() -> Result<bool> {
// flush/close may throw casacore::AipsError; an exception escaping a
// pool task would terminate the process, so convert it to a Status.
try {
tp->flush(false);
tp->close();
return true;
})));
}
auto all_done = arrow::All(results);
all_done.Wait();
return true;
} catch (const std::exception& e) {
return Status::Invalid("Error closing table: ", e.what());
}
return true;
})));
}
auto all_done = arrow::All(results);
ARROW_ASSIGN_OR_RAISE(auto outcomes, all_done.MoveResult());
// Drain any late-scheduled continuations (e.g. Then callbacks) so that
// members are not destroyed while a pool task may still reference them.
for (auto& pp : proxy_pools_) pp.io_pool_->WaitForIdle();
// Surface the first close failure, if any (still leaving the proxy closed).
for (const auto& outcome : outcomes) {
ARROW_RETURN_NOT_OK(outcome.status());
}
return false;
return true;
}

IsolatedTableProxy::~IsolatedTableProxy() {
Expand Down
Loading
Loading