Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • 22:56

    jeremydmiller on optimization

    Separated out CommandBus from M… Pulled MessagePublisher out of … renamed MessageContext to Execu… and 2 more (compare)

  • 17:46

    oskardudycz on master

    Updated link in README.md to 3.… (compare)

  • 17:46

    oskardudycz on master

    Updated link in README.md to 3.… (compare)

  • 17:42

    oskardudycz on 3.14.1

    (compare)

  • 17:42

    oskardudycz on 3.14.1

    (compare)

  • 17:39

    oskardudycz on 3.14.0

    (compare)

  • 17:39

    oskardudycz on 3.14.0

    (compare)

  • 17:33

    oskardudycz on 4.0.2

    (compare)

  • 17:33

    oskardudycz on 4.0.2

    (compare)

  • 17:30

    oskardudycz on master

    Used Weasel 1.0.4 with a fix fo… (compare)

  • 17:30

    oskardudycz on master

    Used Weasel 1.0.4 with a fix fo… (compare)

  • 17:30

    oskardudycz on weasel_1.0.4

    (compare)

  • 17:30

    oskardudycz on weasel_1.0.4

    (compare)

  • 17:30
    oskardudycz closed #1944
  • 17:30
    oskardudycz closed #1944
  • 17:30
    oskardudycz closed #1940
  • 17:30
    oskardudycz closed #1940
  • 17:21
    oskardudycz edited #1944
  • 17:21
    oskardudycz edited #1944
  • 17:21
    oskardudycz edited #1944
Jeremy D. Miller
@jeremydmiller
@jedidja Gimme about an hour and I’ll write it up on #1680?
Jedidja
@jedidja
@jeremydmiller Sure, no rush - when you get a chance. Thank you! My plan is to spend a bit of time on it each day along with the prototypes I'm working on.
Jeremy D. Miller
@jeremydmiller
@jedidja Sorry, I got sucked into Zoom meetings and lost track of this. I’m going into it now...
Jeremy D. Miller
@jeremydmiller
@jedidja See if any of this helps, and don’t hesitate to just keep asking questions: JasperFx/marten#1680
Thanks for taking this on!
Jedidja
@jedidja
@jeremydmiller Will take a look now and ... yes .. there will probably be more questions :) Thanks for the initial notes!
Jeremy D. Miller
@jeremydmiller
No, thank you!
Jedidja
@jedidja
:)
Jedidja
@jedidja

@jeremydmiller I think I understand what AggregateStreamAsync() is doing, and it seems somewhat straightforward to create the AggregateTo method if it were in EventStore. But as an extension method, I'm a bit lost.

Also, I may have gone down a rabbit hole via ProjectionCollection to AggregateProjection.Codegen.cs ... eep. Pretty sure you weren't suggesting I duplicate any of that :)

[1] As a starting point, is this vaguely what you were suggesting? Questions in comments as well.

public static class EventStoreExtensions
{
    public static T AggregateTo<T>(this IMartenQueryable<IEvent> queryable) where T : class
    {
        var events = queryable.ToList();

        // Should I be getting this from ProjectionCollection instead somehow?
        var projection = new AggregateProjection<T>();

        // Seems like I can create an aggregator in a couple ways ...
        var aggregatorOne = projection.Build(new StoreOptions());
        var aggregatorTwo = projection.BuildLiveAggregator();

        // ... but there's no session available for Build()
        // and I think we want to reuse this to call Apply.
        var aggregate = aggregatorOne.Build(events, session, null);

        return aggregate;
    }
}

[2] Where would be the appropriate place to add the first test? Much happier when I can see tests fail and then work on the code :)

Jeremy D. Miller
@jeremydmiller
Yeah, no:) You’ll need to “find” the pre-registered AggregateProjection<T> the exact same way that AggregateStreamAsync() does. You need the dynamic code stuff to be memoized because it’s expensive to build. I think the tests would go in their own code file just under /Events. Just give it a descriptive name like `AggregateTo_Linq_Operator_Tests” or some such thing.
And if it comes down to it, just make it work w/ backing tests and it’s no big deal for me to deal w/ optimizations later
And yeah, that’s very close. Didn’t mean to make it sound like you were too far off other than don’t build up the AggregateProjection<T> yourself and do the memoization.
Jedidja
@jedidja

You’ll need to “find” the pre-registered AggregateProjection<T> the exact same way that AggregateStreamAsync() does

I'm definitely missing something. Presumably there's no "global" way to get to the ProjectionCollection that holds the pre-registered projections? It appears to live in EventGraph but I'm not sure how to access that in an extension method. AggregateStreamAsync has access to DocumentStorewhich leads to Events which leads to Projections but all I've got is an enumeration of IEvent :)

(From AggregateStreamAsync)
            var aggregator = _store.Events.Projections.AggregatorFor<T>();
            var aggregate = await aggregator.BuildAsync(events, _session, state, token);
Jeremy D. Miller
@jeremydmiller
You’ve got an IMartenQueryable<IEvent> when you trigger this off. One second while I load the code
Jedidja
@jedidja
Hmm. Sorry I must have overlooked something in the interface.
Jeremy D. Miller
@jeremydmiller
Okay, this is gonna be a little fugly. We can add an internal getter property for the current IMartenSession in MartenQueryable<T>. In your extension method, upcast to the concrete type, grab its IMartenSession, which gets you Options.Events.Projections.AggregatorFor<T>() and pretend for now that neither of us has ever heard of the Law of Demeter.
Don’t worry too much about making things clean upfront is my vote. Get the tests passing, then we worry more about the internal structures and who exposes who.
Jedidja
@jedidja
Ok :) Will do.
Thanks again. Nothing like day one of working in a new codebase heh.
Jeremy D. Miller
@jeremydmiller
And Marten isn’t typical just due to what it is.
Jedidja
@jedidja
Just adds to the fun :D
Jedidja
@jedidja
@jeremydmiller Put together a tiny PR in my own fork for when you get a chance to comment. jedidja/marten#1 ... no rush (signing off for the day now)
4 replies
Michael Rosario
@michaelprosario
To Jeremy Miller and team.. I wanted to thank you for all your hard work on this project. It's been fun to leverage Marten for my side projects. Excited to share the tech with my user group.
Oskar Dudycz
@oskardudycz
@michaelprosario thank you for the kind words :) Send the feedback after you share it :)
Alex Frie
@agf2413_gitlab
I am having some problems storing and reading primitive types in marten.
If I store a DateTimeOffset or int as a type object, marten will read these as DateTime and Long.
Unlike custom objects Marten don't store any informatin about the $type, and therefore don't have much to go on since the property is of type object.
Is there a way to tell marten to store type information for primitive types aswell, or do I need to wrap all primitive objects in a custom class for it to work with type object?
Oskar Dudycz
@oskardudycz
Do you have issue with other primitives or only with DateTime related?
Alex Frie
@agf2413_gitlab
I only tested with int, DateTimeOffset and string.
String is fine, but int(int32) is read as long(int64) and DateTimeOffset is read as DateTime.
Oskar Dudycz
@oskardudycz
Yes, the DateTime is special, as it's not precisely primitive
As we're using Npgsql as the provider we're following the recommendation from them: https://www.npgsql.org/doc/types/datetime.html
I don't think that we're doing much more customisation on what's described there
Btw. we also support NodaTime (at least for Newtonsoft JSON.NET)
This can help on time handling
Jeremy D. Miller
@jeremydmiller
@agf2413_gitlab Marten isn’t really meant to be used that way. If you’re just storing primitives, why not just use Postgresql as an RDBMS?
Alex Frie
@agf2413_gitlab
I am storing custom objects. I am just also storing some primitives.
Taking a simple example:
// This works
class1 {
 public int IntProperty {get; set;}
}
//This does not work
class2 {
  public object IntProperty {get; set;}
}
//This works
class3 {
  public object LongProperty {get; set;}
}
Jeremy D. Miller
@jeremydmiller
Well, yeah:) That’s just not an idiomatic usage of Marten or the JSON serializers for that matter.
Alex Frie
@agf2413_gitlab

I get this isn't a normal way of using Marten.
A workaround would be to create a wrapper class like this:

class CustomInt {
  public int Value {get; set;}
}

class class1 {
  public CustomInt IntProperty {get; set;
}

Now marten will store type information for CustomInt, and have a property of int to deserialize to. It just seems like a fun workaround in order to force marten to write a type definition for simple types.
So while I get this is certainly not the intended use case, I was wondering if there was some sort of support to force type definitions on all types, including primitive types.

Oskar Dudycz
@oskardudycz
I think that there is no issue with primitives
the issue is that you're trying to use them as objects.
You can safely store primitives types, as you showed in your samples.
With object serialiser don't know precisely what would be the type of that.
You can write custom extension to serialisers if you really need to support that case
Json.NET is really pluggable
Alex Frie
@agf2413_gitlab
Yeah you are right.
The use case is that I have a List<object> that can contain both primitives and objects.
I will try and look at a custom serialiser, or changing the structure to not have primitive types in the list. Thanks :)
Jeremy D. Miller
@jeremydmiller
Or just configure Newtonsoft to always embed type information. That might knock out some of the Linq querying though
JT
@Hawxy
Hello, mind if I get a review of #1769? If you're all fine with that direction, I'd like to get that first pass merged in and create an issue + continue with additional annotations whilst I'm on easter break.
Oskar Dudycz
@oskardudycz
Hi, I’ll try to review this today when I’ll be in front of computer 👍
1 reply
Jeremy D. Miller
@jeremydmiller
Hey world, here’s my latest “state of the V4 release”: https://github.com/JasperFx/marten/discussions/1734#discussioncomment-575826
^^^ @oskardudycz @mysticmind @Hawxy @JohnCampionJr