Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release/v1.0.0 rc3 hotfixes #2206

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/bindings-csharp/BSATN.Codegen/BSATN.Codegen.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<AssemblyName>SpacetimeDB.BSATN.Codegen</AssemblyName>
<Version>1.0.0-rc3</Version>
<Version>1.0.0-rc3-hotfix3</Version>
<Title>SpacetimeDB BSATN Codegen</Title>
<Description>The SpacetimeDB BSATN Codegen implements the Roslyn incremental generators for BSATN serialization/deserialization in C#.</Description>
</PropertyGroup>
Expand Down
12 changes: 12 additions & 0 deletions crates/bindings-csharp/BSATN.Runtime.Tests/Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,16 @@ public static void NonHexStrings()
() => Address.FromHexString("these are not hex characters....")
);
}

[Fact]
public static void TimestampConversionChecks()
{
ulong us = 1737582793990639;
var time = ScheduleAt.DateTimeOffsetFromMicrosSinceUnixEpoch(us);

Assert.Equal(ScheduleAt.ToMicrosecondsSinceUnixEpoch(time), us);

var interval = ScheduleAt.TimeSpanFromMicroseconds(us);
Assert.Equal(ScheduleAt.ToMicroseconds(interval), us);
}
}
2 changes: 1 addition & 1 deletion crates/bindings-csharp/BSATN.Runtime/BSATN.Runtime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<AssemblyName>SpacetimeDB.BSATN.Runtime</AssemblyName>
<Version>1.0.0-rc3</Version>
<Version>1.0.0-rc3-hotfix3</Version>
<Title>SpacetimeDB BSATN Runtime</Title>
<Description>The SpacetimeDB BSATN Runtime implements APIs for BSATN serialization/deserialization in C#.</Description>
</PropertyGroup>
Expand Down
29 changes: 29 additions & 0 deletions crates/bindings-csharp/BSATN.Runtime/Builtins.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,31 @@ public sealed record Time(DateTimeOffset Time_) : ScheduleAt;

public static implicit operator ScheduleAt(DateTimeOffset time) => new Time(time);

/// <summary>
/// There are 10 C# Timestamp "Ticks" per microsecond.
/// </summary>
public static readonly ulong TicksPerMicrosecond = 10;

public static ulong ToMicroseconds(TimeSpan interval)
{
return (ulong)interval.Ticks / TicksPerMicrosecond;
}

public static TimeSpan TimeSpanFromMicroseconds(ulong intervalMicros)
{
return TimeSpan.FromTicks((long)(TicksPerMicrosecond * intervalMicros));
}

public static ulong ToMicrosecondsSinceUnixEpoch(DateTimeOffset time)
{
return ToMicroseconds(time - DateTimeOffset.UnixEpoch);
}

public static DateTimeOffset DateTimeOffsetFromMicrosSinceUnixEpoch(ulong microsSinceUnixEpoch)
{
return DateTimeOffset.UnixEpoch + TimeSpanFromMicroseconds(microsSinceUnixEpoch);
}

public readonly partial struct BSATN : IReadWrite<ScheduleAt>
{
[SpacetimeDB.Type]
Expand Down Expand Up @@ -289,6 +314,10 @@ public void Write(BinaryWriter writer, ScheduleAt value)
public AlgebraicType GetAlgebraicType(ITypeRegistrar registrar) =>
// Constructing a custom one instead of ScheduleAtRepr.GetAlgebraicType()
// to avoid leaking the internal *Repr wrappers in generated SATS.
// We are leveraging the fact that single-element structs are byte-compatible with their elements
// when parsing BSATN.
// TODO: this might break when working with other formats like JSON, but this is all going to be rewritten
// anyway with Phoebe's Timestamp PR.
new AlgebraicType.Sum(
[
new("Interval", new AlgebraicType.U64(default)),
Expand Down
8 changes: 4 additions & 4 deletions crates/bindings-csharp/BSATN.Runtime/Repr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ namespace SpacetimeDB.Internal;
[SpacetimeDB.Type] // we should be able to encode it to BSATN too
public partial struct DateTimeOffsetRepr(DateTimeOffset time)
{
public ulong MicrosecondsSinceEpoch = (ulong)time.Ticks / 10;
public ulong MicrosecondsSinceEpoch = ScheduleAt.ToMicrosecondsSinceUnixEpoch(time);

public readonly DateTimeOffset ToStd() =>
DateTimeOffset.UnixEpoch.AddTicks(10 * (long)MicrosecondsSinceEpoch);
ScheduleAt.DateTimeOffsetFromMicrosSinceUnixEpoch(MicrosecondsSinceEpoch);
}

[StructLayout(LayoutKind.Sequential)] // we should be able to use it in FFI
[SpacetimeDB.Type] // we should be able to encode it to BSATN too
public partial struct TimeSpanRepr(TimeSpan duration)
{
public ulong Microseconds = (ulong)duration.Ticks / 10;
public ulong Microseconds = ScheduleAt.ToMicroseconds(duration);

public readonly TimeSpan ToStd() => TimeSpan.FromTicks(10 * (long)Microseconds);
public readonly TimeSpan ToStd() => ScheduleAt.TimeSpanFromMicroseconds(Microseconds);
}
2 changes: 1 addition & 1 deletion crates/bindings-csharp/Codegen/Codegen.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<AssemblyName>SpacetimeDB.Codegen</AssemblyName>
<Version>1.0.0-rc3</Version>
<Version>1.0.0-rc3-hotfix3</Version>
<Title>SpacetimeDB Module Codegen</Title>
<Description>The SpacetimeDB Codegen implements the Roslyn incremental generators for writing SpacetimeDB modules in C#.</Description>
</PropertyGroup>
Expand Down
2 changes: 1 addition & 1 deletion crates/bindings-csharp/Runtime/Runtime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<AssemblyName>SpacetimeDB.Runtime</AssemblyName>
<Version>1.0.0-rc3</Version>
<Version>1.0.0-rc3-hotfix3</Version>
<Title>SpacetimeDB Module Runtime</Title>
<Description>The SpacetimeDB Runtime implements the database runtime bindings for writing SpacetimeDB modules in C#.</Description>
</PropertyGroup>
Expand Down
35 changes: 9 additions & 26 deletions crates/bindings-macro/src/reducer.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use crate::sym;
use crate::util::{check_duplicate_msg, match_meta};
use crate::util::{check_duplicate, check_duplicate_msg, ident_to_litstr, match_meta};
use proc_macro2::{Span, TokenStream};
use quote::{quote, quote_spanned};
use syn::parse::Parser as _;
use syn::spanned::Spanned;
use syn::{FnArg, Ident, ItemFn};
use syn::{FnArg, Ident, ItemFn, LitStr};

#[derive(Default)]
pub(crate) struct ReducerArgs {
name: Option<LitStr>,
lifecycle: Option<LifecycleReducer>,
}

Expand All @@ -18,14 +19,6 @@ enum LifecycleReducer {
Update(Span),
}
impl LifecycleReducer {
fn reducer_name(&self) -> &'static str {
match self {
Self::Init(_) => "__init__",
Self::ClientConnected(_) => "__identity_connected__",
Self::ClientDisconnected(_) => "__identity_disconnected__",
Self::Update(_) => "__update__",
}
}
fn to_lifecycle_value(&self) -> Option<TokenStream> {
let (Self::Init(span) | Self::ClientConnected(span) | Self::ClientDisconnected(span) | Self::Update(span)) =
*self;
Expand Down Expand Up @@ -54,6 +47,10 @@ impl ReducerArgs {
sym::client_connected => set_lifecycle(LifecycleReducer::ClientConnected)?,
sym::client_disconnected => set_lifecycle(LifecycleReducer::ClientDisconnected)?,
sym::update => set_lifecycle(LifecycleReducer::Update)?,
sym::name => {
check_duplicate(&args.name, &meta)?;
args.name = Some(meta.value()?.parse()?);
}
});
Ok(())
})
Expand All @@ -66,21 +63,7 @@ pub(crate) fn reducer_impl(args: ReducerArgs, original_function: &ItemFn) -> syn
let func_name = &original_function.sig.ident;
let vis = &original_function.vis;

// Extract reducer name, making sure it's not `__XXX__` as that's the form we reserve for special reducers.
let reducer_name;
let reducer_name = match &args.lifecycle {
Some(lifecycle) => lifecycle.reducer_name(),
None => {
reducer_name = func_name.to_string();
if reducer_name.starts_with("__") && reducer_name.ends_with("__") {
return Err(syn::Error::new_spanned(
&original_function.sig.ident,
"reserved reducer name",
));
}
&reducer_name
}
};
let reducer_name = args.name.unwrap_or_else(|| ident_to_litstr(func_name));

for param in &original_function.sig.generics.params {
let err = |msg| syn::Error::new_spanned(param, msg);
Expand Down Expand Up @@ -125,7 +108,7 @@ pub(crate) fn reducer_impl(args: ReducerArgs, original_function: &ItemFn) -> syn
}
.into_iter();

let register_describer_symbol = format!("__preinit__20_register_describer_{reducer_name}");
let register_describer_symbol = format!("__preinit__20_register_describer_{}", reducer_name.value());

let lt_params = &original_function.sig.generics;
let lt_where_clause = &lt_params.where_clause;
Expand Down
3 changes: 1 addition & 2 deletions crates/cli/src/subcommands/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,7 @@ fn add_reducer_ctx_to_err(error: &mut String, schema_json: Value, reducer_name:
.map(|kv| kv.0)
.collect::<Vec<_>>();

// Hide pseudo-reducers (assume that any `__XXX__` are such); they shouldn't be callable.
reducers.retain(|&c| !(c.starts_with("__") && c.ends_with("__")));
// TODO(noa): exclude lifecycle reducers

if let Some(best) = find_best_match_for_name(&reducers, reducer_name, None) {
write!(error, "\n\nA reducer with a similar name exists: `{}`", best).unwrap();
Expand Down
5 changes: 2 additions & 3 deletions crates/cli/src/subcommands/generate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ pub fn generate(module: RawModuleDef, lang: Language, namespace: &str) -> anyhow

let reducers = module
.reducers()
.filter(|r| r.lifecycle.is_none())
.map(|reducer| spacetimedb_lib::ReducerDef {
name: reducer.name.clone().into(),
args: reducer.params.elements.to_vec(),
Expand All @@ -268,9 +269,7 @@ pub fn generate(module: RawModuleDef, lang: Language, namespace: &str) -> anyhow
let items = itertools::chain!(
types,
tables.into_iter().map(GenItem::Table),
reducers
.filter(|r| !(r.name.starts_with("__") && r.name.ends_with("__")))
.map(GenItem::Reducer),
reducers.map(GenItem::Reducer),
);

let items: Vec<GenItem> = items.collect();
Expand Down
Loading
Loading