mirror of
https://github.com/GothenburgBitFactory/taskchampion-sync-server.git
synced 2025-06-26 10:54:29 +02:00
Create clients on NoSuchClient error
With this change, the server methods no longer take a `Client` argument and instead fetch the client directly.
This commit is contained in:
parent
dd6cc04d28
commit
e5091c51de
6 changed files with 182 additions and 194 deletions
|
@ -1,5 +1,5 @@
|
||||||
use crate::error::ServerError;
|
use crate::error::ServerError;
|
||||||
use crate::storage::{Client, Snapshot, Storage, StorageTxn};
|
use crate::storage::{Snapshot, Storage, StorageTxn};
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -109,10 +109,12 @@ impl Server {
|
||||||
pub fn get_child_version(
|
pub fn get_child_version(
|
||||||
&self,
|
&self,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
client: Client,
|
|
||||||
parent_version_id: VersionId,
|
parent_version_id: VersionId,
|
||||||
) -> Result<GetVersionResult, ServerError> {
|
) -> Result<GetVersionResult, ServerError> {
|
||||||
let mut txn = self.storage.txn()?;
|
let mut txn = self.storage.txn()?;
|
||||||
|
let client = txn
|
||||||
|
.get_client(client_id)?
|
||||||
|
.ok_or(ServerError::NoSuchClient)?;
|
||||||
|
|
||||||
// If a version with parentVersionId equal to the requested parentVersionId exists, it is
|
// If a version with parentVersionId equal to the requested parentVersionId exists, it is
|
||||||
// returned.
|
// returned.
|
||||||
|
@ -145,11 +147,13 @@ impl Server {
|
||||||
pub fn add_version(
|
pub fn add_version(
|
||||||
&self,
|
&self,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
client: Client,
|
|
||||||
parent_version_id: VersionId,
|
parent_version_id: VersionId,
|
||||||
history_segment: HistorySegment,
|
history_segment: HistorySegment,
|
||||||
) -> Result<(AddVersionResult, SnapshotUrgency), ServerError> {
|
) -> Result<(AddVersionResult, SnapshotUrgency), ServerError> {
|
||||||
let mut txn = self.storage.txn()?;
|
let mut txn = self.storage.txn()?;
|
||||||
|
let client = txn
|
||||||
|
.get_client(client_id)?
|
||||||
|
.ok_or(ServerError::NoSuchClient)?;
|
||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"add_version(client_id: {}, parent_version_id: {})",
|
"add_version(client_id: {}, parent_version_id: {})",
|
||||||
|
@ -204,11 +208,13 @@ impl Server {
|
||||||
pub fn add_snapshot(
|
pub fn add_snapshot(
|
||||||
&self,
|
&self,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
client: Client,
|
|
||||||
version_id: VersionId,
|
version_id: VersionId,
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
) -> Result<(), ServerError> {
|
) -> Result<(), ServerError> {
|
||||||
let mut txn = self.storage.txn()?;
|
let mut txn = self.storage.txn()?;
|
||||||
|
let client = txn
|
||||||
|
.get_client(client_id)?
|
||||||
|
.ok_or(ServerError::NoSuchClient)?;
|
||||||
|
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"add_snapshot(client_id: {}, version_id: {})",
|
"add_snapshot(client_id: {}, version_id: {})",
|
||||||
|
@ -290,9 +296,11 @@ impl Server {
|
||||||
pub fn get_snapshot(
|
pub fn get_snapshot(
|
||||||
&self,
|
&self,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
client: Client,
|
|
||||||
) -> Result<Option<(Uuid, Vec<u8>)>, ServerError> {
|
) -> Result<Option<(Uuid, Vec<u8>)>, ServerError> {
|
||||||
let mut txn = self.storage.txn()?;
|
let mut txn = self.storage.txn()?;
|
||||||
|
let client = txn
|
||||||
|
.get_client(client_id)?
|
||||||
|
.ok_or(ServerError::NoSuchClient)?;
|
||||||
|
|
||||||
Ok(if let Some(snap) = client.snapshot {
|
Ok(if let Some(snap) = client.snapshot {
|
||||||
txn.get_snapshot_data(client_id, snap.version_id)?
|
txn.get_snapshot_data(client_id, snap.version_id)?
|
||||||
|
@ -331,8 +339,8 @@ mod test {
|
||||||
num_versions: u32,
|
num_versions: u32,
|
||||||
snapshot_version: Option<u32>,
|
snapshot_version: Option<u32>,
|
||||||
snapshot_days_ago: Option<i64>,
|
snapshot_days_ago: Option<i64>,
|
||||||
) -> anyhow::Result<(Server, Uuid, Client, Vec<Uuid>)> {
|
) -> anyhow::Result<(Server, Uuid, Vec<Uuid>)> {
|
||||||
let (server, (client_id, client, versions)) = setup(|txn| {
|
let (server, (client_id, versions)) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let mut versions = vec![];
|
let mut versions = vec![];
|
||||||
|
|
||||||
|
@ -361,10 +369,9 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, versions))
|
||||||
Ok((client_id, client, versions))
|
|
||||||
})?;
|
})?;
|
||||||
Ok((server, client_id, client, versions))
|
Ok((server, client_id, versions))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Utility function to check the results of an add_version call
|
/// Utility function to check the results of an add_version call
|
||||||
|
@ -447,16 +454,15 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_child_version_not_found_initial_nil() -> anyhow::Result<()> {
|
fn get_child_version_not_found_initial_nil() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client)) = setup(|txn| {
|
let (server, client_id) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
txn.new_client(client_id, NIL_VERSION_ID)?;
|
txn.new_client(client_id, NIL_VERSION_ID)?;
|
||||||
|
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok(client_id)
|
||||||
Ok((client_id, client))
|
|
||||||
})?;
|
})?;
|
||||||
// when no latest version exists, the first version is NotFound
|
// when no latest version exists, the first version is NotFound
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
server.get_child_version(client_id, client, NIL_VERSION_ID)?,
|
server.get_child_version(client_id, NIL_VERSION_ID)?,
|
||||||
GetVersionResult::NotFound
|
GetVersionResult::NotFound
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -464,18 +470,17 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_child_version_not_found_initial_continuing() -> anyhow::Result<()> {
|
fn get_child_version_not_found_initial_continuing() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client)) = setup(|txn| {
|
let (server, client_id) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
txn.new_client(client_id, NIL_VERSION_ID)?;
|
txn.new_client(client_id, NIL_VERSION_ID)?;
|
||||||
|
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok(client_id)
|
||||||
Ok((client_id, client))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// when no latest version exists, _any_ child version is NOT_FOUND. This allows syncs to
|
// when no latest version exists, _any_ child version is NOT_FOUND. This allows syncs to
|
||||||
// start to a new server even if the client already has been uploading to another service.
|
// start to a new server even if the client already has been uploading to another service.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
server.get_child_version(client_id, client, Uuid::new_v4(),)?,
|
server.get_child_version(client_id, Uuid::new_v4(),)?,
|
||||||
GetVersionResult::NotFound
|
GetVersionResult::NotFound
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -483,19 +488,18 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_child_version_not_found_up_to_date() -> anyhow::Result<()> {
|
fn get_child_version_not_found_up_to_date() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client, parent_version_id)) = setup(|txn| {
|
let (server, (client_id, parent_version_id)) = setup(|txn| {
|
||||||
// add a parent version, but not the requested child version
|
// add a parent version, but not the requested child version
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let parent_version_id = Uuid::new_v4();
|
let parent_version_id = Uuid::new_v4();
|
||||||
txn.new_client(client_id, parent_version_id)?;
|
txn.new_client(client_id, parent_version_id)?;
|
||||||
txn.add_version(client_id, parent_version_id, NIL_VERSION_ID, vec![])?;
|
txn.add_version(client_id, parent_version_id, NIL_VERSION_ID, vec![])?;
|
||||||
|
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, parent_version_id))
|
||||||
Ok((client_id, client, parent_version_id))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
server.get_child_version(client_id, client, parent_version_id)?,
|
server.get_child_version(client_id, parent_version_id)?,
|
||||||
GetVersionResult::NotFound
|
GetVersionResult::NotFound
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -503,7 +507,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_child_version_gone_not_latest() -> anyhow::Result<()> {
|
fn get_child_version_gone_not_latest() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client)) = setup(|txn| {
|
let (server, client_id) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
|
|
||||||
// Add a parent version, but not the requested parent version
|
// Add a parent version, but not the requested parent version
|
||||||
|
@ -511,12 +515,11 @@ mod test {
|
||||||
txn.new_client(client_id, parent_version_id)?;
|
txn.new_client(client_id, parent_version_id)?;
|
||||||
txn.add_version(client_id, parent_version_id, NIL_VERSION_ID, vec![])?;
|
txn.add_version(client_id, parent_version_id, NIL_VERSION_ID, vec![])?;
|
||||||
|
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok(client_id)
|
||||||
Ok((client_id, client))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
server.get_child_version(client_id, client, Uuid::new_v4(),)?,
|
server.get_child_version(client_id, Uuid::new_v4(),)?,
|
||||||
GetVersionResult::Gone
|
GetVersionResult::Gone
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -524,32 +527,24 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_child_version_found() -> anyhow::Result<()> {
|
fn get_child_version_found() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client, version_id, parent_version_id, history_segment)) =
|
let (server, (client_id, version_id, parent_version_id, history_segment)) = setup(|txn| {
|
||||||
setup(|txn| {
|
let client_id = Uuid::new_v4();
|
||||||
let client_id = Uuid::new_v4();
|
let version_id = Uuid::new_v4();
|
||||||
let version_id = Uuid::new_v4();
|
let parent_version_id = Uuid::new_v4();
|
||||||
let parent_version_id = Uuid::new_v4();
|
let history_segment = b"abcd".to_vec();
|
||||||
let history_segment = b"abcd".to_vec();
|
|
||||||
|
|
||||||
txn.new_client(client_id, version_id)?;
|
txn.new_client(client_id, version_id)?;
|
||||||
txn.add_version(
|
txn.add_version(
|
||||||
client_id,
|
client_id,
|
||||||
version_id,
|
version_id,
|
||||||
parent_version_id,
|
parent_version_id,
|
||||||
history_segment.clone(),
|
history_segment.clone(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, version_id, parent_version_id, history_segment))
|
||||||
Ok((
|
})?;
|
||||||
client_id,
|
|
||||||
client,
|
|
||||||
version_id,
|
|
||||||
parent_version_id,
|
|
||||||
history_segment,
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
server.get_child_version(client_id, client, parent_version_id)?,
|
server.get_child_version(client_id, parent_version_id)?,
|
||||||
GetVersionResult::Success {
|
GetVersionResult::Success {
|
||||||
version_id,
|
version_id,
|
||||||
parent_version_id,
|
parent_version_id,
|
||||||
|
@ -561,13 +556,11 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_version_conflict() -> anyhow::Result<()> {
|
fn add_version_conflict() -> anyhow::Result<()> {
|
||||||
let (server, client_id, client, versions) = av_setup(3, None, None)?;
|
let (server, client_id, versions) = av_setup(3, None, None)?;
|
||||||
|
|
||||||
// try to add a child of a version other than the latest
|
// try to add a child of a version other than the latest
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
server
|
server.add_version(client_id, versions[1], vec![3, 6, 9])?.0,
|
||||||
.add_version(client_id, client, versions[1], vec![3, 6, 9])?
|
|
||||||
.0,
|
|
||||||
AddVersionResult::ExpectedParentVersion(versions[2])
|
AddVersionResult::ExpectedParentVersion(versions[2])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -584,9 +577,9 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_version_with_existing_history() -> anyhow::Result<()> {
|
fn add_version_with_existing_history() -> anyhow::Result<()> {
|
||||||
let (server, client_id, client, versions) = av_setup(1, None, None)?;
|
let (server, client_id, versions) = av_setup(1, None, None)?;
|
||||||
|
|
||||||
let result = server.add_version(client_id, client, versions[0], vec![3, 6, 9])?;
|
let result = server.add_version(client_id, versions[0], vec![3, 6, 9])?;
|
||||||
|
|
||||||
av_success_check(
|
av_success_check(
|
||||||
&server,
|
&server,
|
||||||
|
@ -603,10 +596,10 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_version_with_no_history() -> anyhow::Result<()> {
|
fn add_version_with_no_history() -> anyhow::Result<()> {
|
||||||
let (server, client_id, client, versions) = av_setup(0, None, None)?;
|
let (server, client_id, versions) = av_setup(0, None, None)?;
|
||||||
|
|
||||||
let parent_version_id = Uuid::nil();
|
let parent_version_id = Uuid::nil();
|
||||||
let result = server.add_version(client_id, client, parent_version_id, vec![3, 6, 9])?;
|
let result = server.add_version(client_id, parent_version_id, vec![3, 6, 9])?;
|
||||||
|
|
||||||
av_success_check(
|
av_success_check(
|
||||||
&server,
|
&server,
|
||||||
|
@ -623,9 +616,9 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_version_success_recent_snapshot() -> anyhow::Result<()> {
|
fn add_version_success_recent_snapshot() -> anyhow::Result<()> {
|
||||||
let (server, client_id, client, versions) = av_setup(1, Some(0), None)?;
|
let (server, client_id, versions) = av_setup(1, Some(0), None)?;
|
||||||
|
|
||||||
let result = server.add_version(client_id, client, versions[0], vec![1, 2, 3])?;
|
let result = server.add_version(client_id, versions[0], vec![1, 2, 3])?;
|
||||||
|
|
||||||
av_success_check(
|
av_success_check(
|
||||||
&server,
|
&server,
|
||||||
|
@ -643,9 +636,9 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn add_version_success_aged_snapshot() -> anyhow::Result<()> {
|
fn add_version_success_aged_snapshot() -> anyhow::Result<()> {
|
||||||
// one snapshot, but it was 50 days ago
|
// one snapshot, but it was 50 days ago
|
||||||
let (server, client_id, client, versions) = av_setup(1, Some(0), Some(50))?;
|
let (server, client_id, versions) = av_setup(1, Some(0), Some(50))?;
|
||||||
|
|
||||||
let result = server.add_version(client_id, client, versions[0], vec![1, 2, 3])?;
|
let result = server.add_version(client_id, versions[0], vec![1, 2, 3])?;
|
||||||
|
|
||||||
av_success_check(
|
av_success_check(
|
||||||
&server,
|
&server,
|
||||||
|
@ -663,10 +656,10 @@ mod test {
|
||||||
#[test]
|
#[test]
|
||||||
fn add_version_success_snapshot_many_versions_ago() -> anyhow::Result<()> {
|
fn add_version_success_snapshot_many_versions_ago() -> anyhow::Result<()> {
|
||||||
// one snapshot, but it was 50 versions ago
|
// one snapshot, but it was 50 versions ago
|
||||||
let (mut server, client_id, client, versions) = av_setup(50, Some(0), None)?;
|
let (mut server, client_id, versions) = av_setup(50, Some(0), None)?;
|
||||||
server.config.snapshot_versions = 30;
|
server.config.snapshot_versions = 30;
|
||||||
|
|
||||||
let result = server.add_version(client_id, client, versions[49], vec![1, 2, 3])?;
|
let result = server.add_version(client_id, versions[49], vec![1, 2, 3])?;
|
||||||
|
|
||||||
av_success_check(
|
av_success_check(
|
||||||
&server,
|
&server,
|
||||||
|
@ -683,7 +676,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_snapshot_success_latest() -> anyhow::Result<()> {
|
fn add_snapshot_success_latest() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client, version_id)) = setup(|txn| {
|
let (server, (client_id, version_id)) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let version_id = Uuid::new_v4();
|
let version_id = Uuid::new_v4();
|
||||||
|
|
||||||
|
@ -692,10 +685,9 @@ mod test {
|
||||||
txn.add_version(client_id, version_id, NIL_VERSION_ID, vec![])?;
|
txn.add_version(client_id, version_id, NIL_VERSION_ID, vec![])?;
|
||||||
|
|
||||||
// add a snapshot for that version
|
// add a snapshot for that version
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, version_id))
|
||||||
Ok((client_id, client, version_id))
|
|
||||||
})?;
|
})?;
|
||||||
server.add_snapshot(client_id, client, version_id, vec![1, 2, 3])?;
|
server.add_snapshot(client_id, version_id, vec![1, 2, 3])?;
|
||||||
|
|
||||||
// verify the snapshot
|
// verify the snapshot
|
||||||
let mut txn = server.txn()?;
|
let mut txn = server.txn()?;
|
||||||
|
@ -713,7 +705,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_snapshot_success_older() -> anyhow::Result<()> {
|
fn add_snapshot_success_older() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client, version_id_1)) = setup(|txn| {
|
let (server, (client_id, version_id_1)) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let version_id_1 = Uuid::new_v4();
|
let version_id_1 = Uuid::new_v4();
|
||||||
let version_id_2 = Uuid::new_v4();
|
let version_id_2 = Uuid::new_v4();
|
||||||
|
@ -723,11 +715,10 @@ mod test {
|
||||||
txn.add_version(client_id, version_id_1, NIL_VERSION_ID, vec![])?;
|
txn.add_version(client_id, version_id_1, NIL_VERSION_ID, vec![])?;
|
||||||
txn.add_version(client_id, version_id_2, version_id_1, vec![])?;
|
txn.add_version(client_id, version_id_2, version_id_1, vec![])?;
|
||||||
|
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, version_id_1))
|
||||||
Ok((client_id, client, version_id_1))
|
|
||||||
})?;
|
})?;
|
||||||
// add a snapshot for version 1
|
// add a snapshot for version 1
|
||||||
server.add_snapshot(client_id, client, version_id_1, vec![1, 2, 3])?;
|
server.add_snapshot(client_id, version_id_1, vec![1, 2, 3])?;
|
||||||
|
|
||||||
// verify the snapshot
|
// verify the snapshot
|
||||||
let mut txn = server.txn()?;
|
let mut txn = server.txn()?;
|
||||||
|
@ -745,7 +736,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_snapshot_fails_no_such() -> anyhow::Result<()> {
|
fn add_snapshot_fails_no_such() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client)) = setup(|txn| {
|
let (server, client_id) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let version_id_1 = Uuid::new_v4();
|
let version_id_1 = Uuid::new_v4();
|
||||||
let version_id_2 = Uuid::new_v4();
|
let version_id_2 = Uuid::new_v4();
|
||||||
|
@ -756,12 +747,11 @@ mod test {
|
||||||
txn.add_version(client_id, version_id_2, version_id_1, vec![])?;
|
txn.add_version(client_id, version_id_2, version_id_1, vec![])?;
|
||||||
|
|
||||||
// add a snapshot for unknown version
|
// add a snapshot for unknown version
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok(client_id)
|
||||||
Ok((client_id, client))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let version_id_unk = Uuid::new_v4();
|
let version_id_unk = Uuid::new_v4();
|
||||||
server.add_snapshot(client_id, client, version_id_unk, vec![1, 2, 3])?;
|
server.add_snapshot(client_id, version_id_unk, vec![1, 2, 3])?;
|
||||||
|
|
||||||
// verify the snapshot does not exist
|
// verify the snapshot does not exist
|
||||||
let mut txn = server.txn()?;
|
let mut txn = server.txn()?;
|
||||||
|
@ -773,7 +763,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_snapshot_fails_too_old() -> anyhow::Result<()> {
|
fn add_snapshot_fails_too_old() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client, version_ids)) = setup(|txn| {
|
let (server, (client_id, version_ids)) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let mut version_id = Uuid::new_v4();
|
let mut version_id = Uuid::new_v4();
|
||||||
let mut parent_version_id = Uuid::nil();
|
let mut parent_version_id = Uuid::nil();
|
||||||
|
@ -789,10 +779,9 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a snapshot for the earliest of those
|
// add a snapshot for the earliest of those
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, version_ids))
|
||||||
Ok((client_id, client, version_ids))
|
|
||||||
})?;
|
})?;
|
||||||
server.add_snapshot(client_id, client, version_ids[0], vec![1, 2, 3])?;
|
server.add_snapshot(client_id, version_ids[0], vec![1, 2, 3])?;
|
||||||
|
|
||||||
// verify the snapshot does not exist
|
// verify the snapshot does not exist
|
||||||
let mut txn = server.txn()?;
|
let mut txn = server.txn()?;
|
||||||
|
@ -804,7 +793,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_snapshot_fails_newer_exists() -> anyhow::Result<()> {
|
fn add_snapshot_fails_newer_exists() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client, version_ids)) = setup(|txn| {
|
let (server, (client_id, version_ids)) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let mut version_id = Uuid::new_v4();
|
let mut version_id = Uuid::new_v4();
|
||||||
let mut parent_version_id = Uuid::nil();
|
let mut parent_version_id = Uuid::nil();
|
||||||
|
@ -830,11 +819,10 @@ mod test {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// add a snapshot for the earliest of those
|
// add a snapshot for the earliest of those
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, version_ids))
|
||||||
Ok((client_id, client, version_ids))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
server.add_snapshot(client_id, client, version_ids[0], vec![9, 9, 9])?;
|
server.add_snapshot(client_id, version_ids[0], vec![9, 9, 9])?;
|
||||||
|
|
||||||
// verify the snapshot was not replaced
|
// verify the snapshot was not replaced
|
||||||
let mut txn = server.txn()?;
|
let mut txn = server.txn()?;
|
||||||
|
@ -852,18 +840,17 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn add_snapshot_fails_nil_version() -> anyhow::Result<()> {
|
fn add_snapshot_fails_nil_version() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client)) = setup(|txn| {
|
let (server, client_id) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
|
|
||||||
// just set up the client
|
// just set up the client
|
||||||
txn.new_client(client_id, NIL_VERSION_ID)?;
|
txn.new_client(client_id, NIL_VERSION_ID)?;
|
||||||
|
|
||||||
// add a snapshot for the nil version
|
// add a snapshot for the nil version
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok(client_id)
|
||||||
Ok((client_id, client))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
server.add_snapshot(client_id, client, NIL_VERSION_ID, vec![9, 9, 9])?;
|
server.add_snapshot(client_id, NIL_VERSION_ID, vec![9, 9, 9])?;
|
||||||
|
|
||||||
// verify the snapshot does not exist
|
// verify the snapshot does not exist
|
||||||
let mut txn = server.txn()?;
|
let mut txn = server.txn()?;
|
||||||
|
@ -875,7 +862,7 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_snapshot_found() -> anyhow::Result<()> {
|
fn get_snapshot_found() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client, data, snapshot_version_id)) = setup(|txn| {
|
let (server, (client_id, data, snapshot_version_id)) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
let data = vec![1, 2, 3];
|
let data = vec![1, 2, 3];
|
||||||
let snapshot_version_id = Uuid::new_v4();
|
let snapshot_version_id = Uuid::new_v4();
|
||||||
|
@ -890,11 +877,10 @@ mod test {
|
||||||
},
|
},
|
||||||
data.clone(),
|
data.clone(),
|
||||||
)?;
|
)?;
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok((client_id, data, snapshot_version_id))
|
||||||
Ok((client_id, client, data, snapshot_version_id))
|
|
||||||
})?;
|
})?;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
server.get_snapshot(client_id, client)?,
|
server.get_snapshot(client_id)?,
|
||||||
Some((snapshot_version_id, data))
|
Some((snapshot_version_id, data))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -903,14 +889,13 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_snapshot_not_found() -> anyhow::Result<()> {
|
fn get_snapshot_not_found() -> anyhow::Result<()> {
|
||||||
let (server, (client_id, client)) = setup(|txn| {
|
let (server, client_id) = setup(|txn| {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
txn.new_client(client_id, NIL_VERSION_ID)?;
|
txn.new_client(client_id, NIL_VERSION_ID)?;
|
||||||
let client = txn.get_client(client_id)?.unwrap();
|
Ok(client_id)
|
||||||
Ok((client_id, client))
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
assert_eq!(server.get_snapshot(client_id, client)?, None);
|
assert_eq!(server.get_snapshot(client_id)?, None);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use crate::api::{
|
use crate::api::{client_id_header, server_error_to_actix, ServerState, SNAPSHOT_CONTENT_TYPE};
|
||||||
client_id_header, failure_to_ise, server_error_to_actix, ServerState, SNAPSHOT_CONTENT_TYPE,
|
|
||||||
};
|
|
||||||
use actix_web::{error, post, web, HttpMessage, HttpRequest, HttpResponse, Result};
|
use actix_web::{error, post, web, HttpMessage, HttpRequest, HttpResponse, Result};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use taskchampion_sync_server_core::{VersionId, NIL_VERSION_ID};
|
use taskchampion_sync_server_core::VersionId;
|
||||||
|
|
||||||
/// Max snapshot size: 100MB
|
/// Max snapshot size: 100MB
|
||||||
const MAX_SIZE: usize = 100 * 1024 * 1024;
|
const MAX_SIZE: usize = 100 * 1024 * 1024;
|
||||||
|
@ -48,38 +46,20 @@ pub(crate) async fn service(
|
||||||
return Err(error::ErrorBadRequest("No snapshot supplied"));
|
return Err(error::ErrorBadRequest("No snapshot supplied"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// note that we do not open the transaction until the body has been read
|
|
||||||
// completely, to avoid blocking other storage access while that data is
|
|
||||||
// in transit.
|
|
||||||
let client = {
|
|
||||||
let mut txn = server_state.server.txn().map_err(server_error_to_actix)?;
|
|
||||||
|
|
||||||
// get, or create, the client
|
|
||||||
match txn.get_client(client_id).map_err(failure_to_ise)? {
|
|
||||||
Some(client) => client,
|
|
||||||
None => {
|
|
||||||
txn.new_client(client_id, NIL_VERSION_ID)
|
|
||||||
.map_err(failure_to_ise)?;
|
|
||||||
txn.get_client(client_id).map_err(failure_to_ise)?.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
server_state
|
server_state
|
||||||
.server
|
.server
|
||||||
.add_snapshot(client_id, client, version_id, body.to_vec())
|
.add_snapshot(client_id, version_id, body.to_vec())
|
||||||
.map_err(server_error_to_actix)?;
|
.map_err(server_error_to_actix)?;
|
||||||
Ok(HttpResponse::Ok().body(""))
|
Ok(HttpResponse::Ok().body(""))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
|
||||||
use crate::api::CLIENT_ID_HEADER;
|
use crate::api::CLIENT_ID_HEADER;
|
||||||
use crate::WebServer;
|
use crate::WebServer;
|
||||||
use actix_web::{http::StatusCode, test, App};
|
use actix_web::{http::StatusCode, test, App};
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
use taskchampion_sync_server_core::{InMemoryStorage, Storage};
|
use taskchampion_sync_server_core::{InMemoryStorage, Storage, NIL_VERSION_ID};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
|
|
|
@ -6,7 +6,9 @@ use crate::api::{
|
||||||
use actix_web::{error, post, web, HttpMessage, HttpRequest, HttpResponse, Result};
|
use actix_web::{error, post, web, HttpMessage, HttpRequest, HttpResponse, Result};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use taskchampion_sync_server_core::{AddVersionResult, SnapshotUrgency, VersionId, NIL_VERSION_ID};
|
use taskchampion_sync_server_core::{
|
||||||
|
AddVersionResult, ServerError, SnapshotUrgency, VersionId, NIL_VERSION_ID,
|
||||||
|
};
|
||||||
|
|
||||||
/// Max history segment size: 100MB
|
/// Max history segment size: 100MB
|
||||||
const MAX_SIZE: usize = 100 * 1024 * 1024;
|
const MAX_SIZE: usize = 100 * 1024 * 1024;
|
||||||
|
@ -55,48 +57,41 @@ pub(crate) async fn service(
|
||||||
return Err(error::ErrorBadRequest("Empty body"));
|
return Err(error::ErrorBadRequest("Empty body"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// note that we do not open the transaction until the body has been read
|
loop {
|
||||||
// completely, to avoid blocking other storage access while that data is
|
return match server_state
|
||||||
// in transit.
|
.server
|
||||||
let client = {
|
.add_version(client_id, parent_version_id, body.to_vec())
|
||||||
let mut txn = server_state.server.txn().map_err(server_error_to_actix)?;
|
{
|
||||||
|
Ok((AddVersionResult::Ok(version_id), snap_urgency)) => {
|
||||||
match txn.get_client(client_id).map_err(failure_to_ise)? {
|
let mut rb = HttpResponse::Ok();
|
||||||
Some(client) => client,
|
rb.append_header((VERSION_ID_HEADER, version_id.to_string()));
|
||||||
None => {
|
match snap_urgency {
|
||||||
|
SnapshotUrgency::None => {}
|
||||||
|
SnapshotUrgency::Low => {
|
||||||
|
rb.append_header((SNAPSHOT_REQUEST_HEADER, "urgency=low"));
|
||||||
|
}
|
||||||
|
SnapshotUrgency::High => {
|
||||||
|
rb.append_header((SNAPSHOT_REQUEST_HEADER, "urgency=high"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(rb.finish())
|
||||||
|
}
|
||||||
|
Ok((AddVersionResult::ExpectedParentVersion(parent_version_id), _)) => {
|
||||||
|
let mut rb = HttpResponse::Conflict();
|
||||||
|
rb.append_header((PARENT_VERSION_ID_HEADER, parent_version_id.to_string()));
|
||||||
|
Ok(rb.finish())
|
||||||
|
}
|
||||||
|
Err(ServerError::NoSuchClient) => {
|
||||||
|
// Create a new client and repeate the `add_version` call.
|
||||||
|
let mut txn = server_state.server.txn().map_err(server_error_to_actix)?;
|
||||||
txn.new_client(client_id, NIL_VERSION_ID)
|
txn.new_client(client_id, NIL_VERSION_ID)
|
||||||
.map_err(failure_to_ise)?;
|
.map_err(failure_to_ise)?;
|
||||||
txn.get_client(client_id).map_err(failure_to_ise)?.unwrap()
|
txn.commit().map_err(failure_to_ise)?;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
Err(e) => Err(server_error_to_actix(e)),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
let (result, snap_urgency) = server_state
|
|
||||||
.server
|
|
||||||
.add_version(client_id, client, parent_version_id, body.to_vec())
|
|
||||||
.map_err(server_error_to_actix)?;
|
|
||||||
|
|
||||||
Ok(match result {
|
|
||||||
AddVersionResult::Ok(version_id) => {
|
|
||||||
let mut rb = HttpResponse::Ok();
|
|
||||||
rb.append_header((VERSION_ID_HEADER, version_id.to_string()));
|
|
||||||
match snap_urgency {
|
|
||||||
SnapshotUrgency::None => {}
|
|
||||||
SnapshotUrgency::Low => {
|
|
||||||
rb.append_header((SNAPSHOT_REQUEST_HEADER, "urgency=low"));
|
|
||||||
}
|
|
||||||
SnapshotUrgency::High => {
|
|
||||||
rb.append_header((SNAPSHOT_REQUEST_HEADER, "urgency=high"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
rb.finish()
|
|
||||||
}
|
|
||||||
AddVersionResult::ExpectedParentVersion(parent_version_id) => {
|
|
||||||
let mut rb = HttpResponse::Conflict();
|
|
||||||
rb.append_header((PARENT_VERSION_ID_HEADER, parent_version_id.to_string()));
|
|
||||||
rb.finish()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -150,6 +145,49 @@ mod test {
|
||||||
assert_eq!(resp.headers().get("X-Parent-Version-Id"), None);
|
assert_eq!(resp.headers().get("X-Parent-Version-Id"), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[actix_rt::test]
|
||||||
|
async fn test_auto_add_client() {
|
||||||
|
let client_id = Uuid::new_v4();
|
||||||
|
let version_id = Uuid::new_v4();
|
||||||
|
let parent_version_id = Uuid::new_v4();
|
||||||
|
let server = WebServer::new(Default::default(), InMemoryStorage::new());
|
||||||
|
let app = App::new().configure(|sc| server.config(sc));
|
||||||
|
let app = test::init_service(app).await;
|
||||||
|
|
||||||
|
let uri = format!("/v1/client/add-version/{}", parent_version_id);
|
||||||
|
let req = test::TestRequest::post()
|
||||||
|
.uri(&uri)
|
||||||
|
.append_header((
|
||||||
|
"Content-Type",
|
||||||
|
"application/vnd.taskchampion.history-segment",
|
||||||
|
))
|
||||||
|
.append_header((CLIENT_ID_HEADER, client_id.to_string()))
|
||||||
|
.set_payload(b"abcd".to_vec())
|
||||||
|
.to_request();
|
||||||
|
let resp = test::call_service(&app, req).await;
|
||||||
|
assert_eq!(resp.status(), StatusCode::OK);
|
||||||
|
|
||||||
|
// the returned version ID is random, but let's check that it's not
|
||||||
|
// the passed parent version ID, at least
|
||||||
|
let new_version_id = resp.headers().get("X-Version-Id").unwrap();
|
||||||
|
let new_version_id = Uuid::parse_str(new_version_id.to_str().unwrap()).unwrap();
|
||||||
|
assert!(new_version_id != version_id);
|
||||||
|
|
||||||
|
// Shapshot should be requested, since there is no existing snapshot
|
||||||
|
let snapshot_request = resp.headers().get("X-Snapshot-Request").unwrap();
|
||||||
|
assert_eq!(snapshot_request, "urgency=high");
|
||||||
|
|
||||||
|
assert_eq!(resp.headers().get("X-Parent-Version-Id"), None);
|
||||||
|
|
||||||
|
// Check that the client really was created
|
||||||
|
{
|
||||||
|
let mut txn = server.server_state.server.txn().unwrap();
|
||||||
|
let client = txn.get_client(client_id).unwrap().unwrap();
|
||||||
|
assert_eq!(client.latest_version_id, new_version_id);
|
||||||
|
assert_eq!(client.snapshot, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_conflict() {
|
async fn test_conflict() {
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
client_id_header, failure_to_ise, server_error_to_actix, ServerState,
|
client_id_header, server_error_to_actix, ServerState, HISTORY_SEGMENT_CONTENT_TYPE,
|
||||||
HISTORY_SEGMENT_CONTENT_TYPE, PARENT_VERSION_ID_HEADER, VERSION_ID_HEADER,
|
PARENT_VERSION_ID_HEADER, VERSION_ID_HEADER,
|
||||||
};
|
};
|
||||||
use actix_web::{error, get, web, HttpRequest, HttpResponse, Result};
|
use actix_web::{error, get, web, HttpRequest, HttpResponse, Result};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use taskchampion_sync_server_core::{GetVersionResult, VersionId};
|
use taskchampion_sync_server_core::{GetVersionResult, ServerError, VersionId};
|
||||||
|
|
||||||
/// Get a child version.
|
/// Get a child version.
|
||||||
///
|
///
|
||||||
|
@ -21,35 +21,28 @@ pub(crate) async fn service(
|
||||||
path: web::Path<VersionId>,
|
path: web::Path<VersionId>,
|
||||||
) -> Result<HttpResponse> {
|
) -> Result<HttpResponse> {
|
||||||
let parent_version_id = path.into_inner();
|
let parent_version_id = path.into_inner();
|
||||||
|
let client_id = client_id_header(&req)?;
|
||||||
let (client, client_id) = {
|
|
||||||
let mut txn = server_state.server.txn().map_err(server_error_to_actix)?;
|
|
||||||
|
|
||||||
let client_id = client_id_header(&req)?;
|
|
||||||
|
|
||||||
let client = txn
|
|
||||||
.get_client(client_id)
|
|
||||||
.map_err(failure_to_ise)?
|
|
||||||
.ok_or_else(|| error::ErrorNotFound("no such client"))?;
|
|
||||||
(client, client_id)
|
|
||||||
};
|
|
||||||
|
|
||||||
return match server_state
|
return match server_state
|
||||||
.server
|
.server
|
||||||
.get_child_version(client_id, client, parent_version_id)
|
.get_child_version(client_id, parent_version_id)
|
||||||
.map_err(server_error_to_actix)?
|
|
||||||
{
|
{
|
||||||
GetVersionResult::Success {
|
Ok(GetVersionResult::Success {
|
||||||
version_id,
|
version_id,
|
||||||
parent_version_id,
|
parent_version_id,
|
||||||
history_segment,
|
history_segment,
|
||||||
} => Ok(HttpResponse::Ok()
|
}) => Ok(HttpResponse::Ok()
|
||||||
.content_type(HISTORY_SEGMENT_CONTENT_TYPE)
|
.content_type(HISTORY_SEGMENT_CONTENT_TYPE)
|
||||||
.append_header((VERSION_ID_HEADER, version_id.to_string()))
|
.append_header((VERSION_ID_HEADER, version_id.to_string()))
|
||||||
.append_header((PARENT_VERSION_ID_HEADER, parent_version_id.to_string()))
|
.append_header((PARENT_VERSION_ID_HEADER, parent_version_id.to_string()))
|
||||||
.body(history_segment)),
|
.body(history_segment)),
|
||||||
GetVersionResult::NotFound => Err(error::ErrorNotFound("no such version")),
|
Ok(GetVersionResult::NotFound) => Err(error::ErrorNotFound("no such version")),
|
||||||
GetVersionResult::Gone => Err(error::ErrorGone("version has been deleted")),
|
Ok(GetVersionResult::Gone) => Err(error::ErrorGone("version has been deleted")),
|
||||||
|
// Note that the HTTP client cannot differentiate `NotFound` and `NoSuchClient`, as both
|
||||||
|
// are a 404 NOT FOUND response. In either case, the HTTP client will typically attempt
|
||||||
|
// to add a new version, which may create the new client at the same time.
|
||||||
|
Err(ServerError::NoSuchClient) => Err(error::ErrorNotFound("no such client")),
|
||||||
|
Err(e) => Err(server_error_to_actix(e)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::api::{
|
use crate::api::{
|
||||||
client_id_header, failure_to_ise, server_error_to_actix, ServerState, SNAPSHOT_CONTENT_TYPE,
|
client_id_header, server_error_to_actix, ServerState, SNAPSHOT_CONTENT_TYPE, VERSION_ID_HEADER,
|
||||||
VERSION_ID_HEADER,
|
|
||||||
};
|
};
|
||||||
use actix_web::{error, get, web, HttpRequest, HttpResponse, Result};
|
use actix_web::{error, get, web, HttpRequest, HttpResponse, Result};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -20,16 +19,9 @@ pub(crate) async fn service(
|
||||||
) -> Result<HttpResponse> {
|
) -> Result<HttpResponse> {
|
||||||
let client_id = client_id_header(&req)?;
|
let client_id = client_id_header(&req)?;
|
||||||
|
|
||||||
let client = {
|
|
||||||
let mut txn = server_state.server.txn().map_err(server_error_to_actix)?;
|
|
||||||
txn.get_client(client_id)
|
|
||||||
.map_err(failure_to_ise)?
|
|
||||||
.ok_or_else(|| error::ErrorNotFound("no such client"))?
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some((version_id, data)) = server_state
|
if let Some((version_id, data)) = server_state
|
||||||
.server
|
.server
|
||||||
.get_snapshot(client_id, client)
|
.get_snapshot(client_id)
|
||||||
.map_err(server_error_to_actix)?
|
.map_err(server_error_to_actix)?
|
||||||
{
|
{
|
||||||
Ok(HttpResponse::Ok()
|
Ok(HttpResponse::Ok()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use actix_web::{error, http::StatusCode, web, HttpRequest, Result, Scope};
|
use actix_web::{error, web, HttpRequest, Result, Scope};
|
||||||
use taskchampion_sync_server_core::{ClientId, Server, ServerError};
|
use taskchampion_sync_server_core::{ClientId, Server, ServerError};
|
||||||
|
|
||||||
mod add_snapshot;
|
mod add_snapshot;
|
||||||
|
@ -38,9 +38,9 @@ pub(crate) fn api_scope() -> Scope {
|
||||||
.service(add_snapshot::service)
|
.service(add_snapshot::service)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a failure::Error to an Actix ISE
|
/// Convert a `anyhow::Error` to an Actix ISE
|
||||||
fn failure_to_ise(err: anyhow::Error) -> impl actix_web::ResponseError {
|
fn failure_to_ise(err: anyhow::Error) -> actix_web::Error {
|
||||||
error::InternalError::new(err, StatusCode::INTERNAL_SERVER_ERROR)
|
error::ErrorInternalServerError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a ServerError to an Actix error
|
/// Convert a ServerError to an Actix error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue