-
Notifications
You must be signed in to change notification settings - Fork 8
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
Simple setup #44
Simple setup #44
Conversation
Simplify for PR. Test field offset. Test Run tests again. Test t File was not saved. simple run Check tests Revert struct. Fix tests. Check some offset thing. Array tests More test fixes. Fix tests Fix check. Fix build. better result types. Set environment variable. Do not run arm tests. Do not fail fast. Test build. Test linux. Another test Print out files. Fix library name. Cp Fix path Fix yaml Try to run tests Fix path Another test Fix pack? Upload nuget packages. Checkout everything. Build props. Remove patch. Test Fix sync. Small fixes. Fix To method. Fixes Several fixed and simplifications. Setup to test more providers and authentication. Extension project. Fix project name. Add support for MongoDB. Simplified code. Batching. Fix deadlock and implement listener. Styling. Deadlock test Temp. Rename file. Service extensions. Test Some improvements. Just some progress. Cache documents. Server project.
7bb772d
to
8567f28
Compare
# Conflicts: # .github/workflows/build.yml
@LSViana Do you know when you have time to review that? I would really like to integrate yjs into our product and the .NET server is essential. So I am little bit in a hurry and have the time to move this forward. I also understand that you don't want to loose control and I don't want to maintain my own fork, because the world does not need 2 .NET yjs servers. So I am a little unsure how to move forward. |
Hi, @SebastianStehle! I'll check your fork later today, I planned it for yesterday but I couldn't do it. However, I believe it's unlikely I'll be able to review everything you added to this PR and this project doesn't have a NuGet package yet anyway, so I'd suggest you to keep using your own fork for the next few days just in case. |
Thanks for the update. The point with the own fork is more that if I just continue with my plans, it causes several problems:
So if I just continue for a few days it is very likely that there will be no merge at all. |
Hi, @SebastianStehle! Don't worry that much about my previous comments. I'm the author of the bindings so far but this project won't run based on what I like, it should be the best for the community. I was trying to make sure we'd not lose control because if I merge all your code today and I don't understand what it does and how it does, that would mean losing control of the library development in my opinion. But, at the same time, I see now that you "cleaned up" the PR and it's now mostly changing files instead of adding new stuff (like the MongoDB and Redis-related code). This will definitely make things easier to review and integrate as soon as possible. |
Yes, I want to make small changes for now and fix the core and then focus on the server projects. So what I would like to achieve:
And when this is done, then I can provide new PRs for all the server stuff. |
Hi, @SebastianStehle! Alright, let's do it. I'll review your changes later today after I finish my regular work & personal tasks, so you should probably expect my replies & review comments tomorrow. |
# Conflicts: # YDotNet/Document/Transactions/Transaction.cs
Hi, @SebastianStehle! I am still going to check the code changes in this PR but I just finished reading your first comment and I have a few questions to ask beforehand:
This is actually an expected behavior. This is inspired by how both Yjs and Yrs work. In Yjs if you try to get a value from a In Yrs, if you try to get a value from a So, in short, I don't see a reason to throw an exception if the type being read doesn't match the underlying type. The approach of yffi of returning
For the scenario [1], both the "throw exception" and "return null" approaches will work fine because the developer knows, when writing the code, that they'll always get a For the scenario [2], the "return null" approach works by relying on the developer to check the What do you think? Is there any case that the "return null" approach was much worse to use than the "throw exception" approach at the point that it justifies this change? Or maybe you're suggesting this because you're used to methods that have a Please, let me know what you think since this kind of change affects the ergonomics of the library. I'm looking for an approach that keeps it easy to use for most people.
Please, can you provide a runnable example of where this happens? I've been developing the library on both Windows and macOS but I never noticed such a bug. Also, if we really have this bug and your change fixes it, we should probably have a unit test with a scenario that ensures it remains working so we don't accidentally break it in the future.
Same as above, it'd be nice to have a runnable example to verify this. For both cases, if you have the time, feel free to add unit tests to "mimic" the problematic scenarios (you can restore the old P/Invoke calls if needed). Sorry for the long comment but I think it's a good starting point to the discussions here. I'll check the code changes the next time I have time available for this project. |
Additionally, this PR will probably be split into smaller pieces as we move since it's currently very wide and, for example, I can't even think of a proper name for it. I'll take care of this task management part, though, so you don't need to worry about it. |
Actually all the changes have something to do with getting the errors fixed: I was never really happy with the null approach, because I am not used to it. My headless CMS Squidex is a lot about working with unmanaged data and so the libraries I use are very similar to Yint, for example:
All of them have some kind of json type that represents one of many values and all work the same. So it was confusing to work with nulls. I would say this is already a strong argument. but there are more:
Case 3 happened with the tests. I have added github actions and was running the tests under all operation systems and I got a log null reference exceptions for Linux: https://github.com/SebastianStehle/ydotnet/actions/runs/6430543358/job/17461698179. I had no idea what was going on. So after the change i have realized that something with the tag must be wrong: https://github.com/SebastianStehle/ydotnet/actions/runs/6432471124/job/17467429093 In the action above, you will notice the MacOS problem: https://github.com/SebastianStehle/ydotnet/actions/runs/6432471124/job/17467429093
This changed after I revisited the pointers. It took my hours to figure this out, but the difference is something with const vs mutable pointers. |
Hi, @SebastianStehle! I'll try to fix all other objective issues and try to merge smaller PRs and then we can keep discussing the API design for the About the other issues, your changes look good to me and it's unfortunate we don't have an easy to reproduce scenario. I've been using macOS & Windows and all tests (except 3 which are broken on purpose until I can check some details with the Yrs team) were passing correctly & consistently. I'll keep an eye out to see if I can detect similar issues in other places of the native bindings. For today, I'm reviewing the code changes but I'm almost running out of time so I'll probably not be able to post comments or merge anything yet. I intend to take care of it tomorrow and during the weekend. |
Hi, About Teststhe tests do not tell the whole truth, because I noticed that it s very flaky. Sometime it depends on the garbage collector and rust. For example 2 things I noticed: This code is buggy: https://github.com/LSViana/ydotnet/blob/main/YDotNet/Document/Doc.cs#L363
Because no managed object holds a reference to the delegate it will eventually be collected by the garbage collector. Then you get an exception that you cannot catch. The problem is that the tests are fast and do not allocate enough memory to trigger GC. So I only had this issue very sporadically and adding a few `GC.Collect´ will help to reproduce it. The following code also creates issues:
Here b is actually deleted so you should not access it anymore, but the problem does not happen all the time. Usually after 50-100 iterations it will fail. About PRsUnfortunately I am not able to provide smaller PRs at the moment. There are several reasons for that but the background is that I need a yjs server for a commercial Open Source project and I have 40-60 hours per week if needed to work on that and obviously your available is lower. it is just a fact, not criticism. Some of the changes are dependent on each other so if I would make small chunks of work I would create a conflict hell on my side or I would have to wait for you. I can also not wait for your input, because it would restrict me too much. Sometimes I also don't know yet, what the best approach is, for example I followed several approaches to improve the memory management and things became a little bit chaotic with that. |
Hi, @SebastianStehle! About this:
I noticed that bug previously and I fixed it already. I discovered it as part of the memory leak investigations (#34) and it's already fixed by now (just not in This and this are the two commits that fixed the problem.
Yeah, that's true. It's not ideal that this code doesn't fail immediately (because the Do you have any suggestions on how this should be fixed on the YDotNet layer?
Don't worry, I wasn't expecting you'd do that. I intend to review and apply your changes to the main repository as soon as I can process them. What's taking me long this week is my main job and the fact I am sick and progressing slower. To be clear, I do intend to push your changes into the repository but I'd really like to do that in a controlled, analytical way and that takes time. I thought it'd be okay for you but in case you're in a hurry to use the project, I was thinking you'd be able to use your own repository for that. Is there anything else I can do to help you while I review & process your PRs & issues? |
I think we can only fix it in .NET by reducing the validity of types to certain scopes like transactions or events. But I am also discussing it with the y-crdt team at the moment: y-crdt/y-crdt#338. I actually had to write a custom test runner to catch these errors: https://github.com/SebastianStehle/ydotnet/blob/improve-output/Tests/YDotNet.Tests.Unit/Program.cs
I don't think so. My main branch is the improve-output branch at the moment. And I am really happy with that. Except the things that I cannot solve. But I found more bugs and made some improvements to the code that I think you will like. But I think the only option to merge it in is so go over the changes in a chat and decide whether we want to use the branch or not. |
Hi, @SebastianStehle! As we discussed earlier today, I'm going to reject this PR since it's now replaced by #55. |
This is cleaned PR now that contains the changes that are necessary to get YDotnet running on all platforms and to have native binaries. So here is what I did:
Binaries
Closes #15
Fixes to Output
The output type was very unexpected because to be close to y-crdt it was returning null when something was not as expected. All similar types (think JToken or JsonElement) throw exceptions and provide a property to check the type. Therefore I made the following changes:
Tag
is not a well known term in the .NET world, so I changed it toType
. This improves performance because you don't need 15 calls to y-crdt to check your type. Also some methods like Null or Undefined don't have a check anymore.Btw: This makes #39 obsolete.
Bug in the Binding 1:
The method
ymap_insert
accepts a pointer to the input. We have passed the struct by value which was working under windows, but under mac and linux. I have no idea why and it took my hours to figure that out. But after changing it to a pointer it works fine now.See: https://github.com/y-crdt/y-crdt/blob/bb26eb73ab4ac6899ad3b6f29f9c9be281ef4a33/yffi/src/lib.rs#L1561
I think there could be room for improvement. With unsafe code we should be able to get the pointer to a struct and therefore avoid the extra memory allocation that is needed here to create a pointer.
Bug in the Binding 2
Under mac I have seen exceptions when working with the
AfterTransactionEventNative
struct. The event is passed as a pointer. Sometimes (See undo manager) it is correct, but in other cases you have to read the pointer to a struct manually. Not sure again what the problem is.