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

.NET 5 support #88

Open
theRainbird opened this issue Jan 26, 2021 · 13 comments
Open

.NET 5 support #88

theRainbird opened this issue Jan 26, 2021 · 13 comments
Assignees

Comments

@theRainbird
Copy link
Contributor

Zyan has currently no support for .NET 5, because .NET Remoting is not available in .NET 5 anymore.
.NET 5 support would be a great.

@theRainbird
Copy link
Contributor Author

I recently created a library to migrate large classic .NET Remoting projects to .NET 5 based on websocket-sharp, named CoreRemoting.
Some parts of the code may be also useful for Zyan to create a transport layer that runs well on .NET 5.

@yallie
Copy link
Member

yallie commented Jan 26, 2021

Hello Hagen, great to hear from you again! :)

The project looks very interesting!
Is it a prototype or you already use it in production?

Some parts of the code may be also useful for Zyan to create a transport layer that runs well on .NET 5.

I've always felt annoyed that such a good library is doomed because of the deprecation of Remoting.
Zyan is used in many projects and still gets quite a lot of bugfixes based on a real world use cases.
Your new library provides a great opportunity to spin off a future-proof fork of Zyan.

Any chances you could sketch up a new transport layer for Zyan based on CoreRemoting?
I remember in the past you once made a working proof-of-concept WCF-based transport for Zyan.

@theRainbird
Copy link
Contributor Author

theRainbird commented Jan 27, 2021

Is it a prototype or you already use it in production?

It will soon be ready for production, after the following features are completed:

There are also some more unit tests needed to ensure good quality.
I'm working on a .NET Remoting based projecs for many years which has more than 1.1 millon lines of code, why it is almost impossible to rewrite using WebAPI or gRPC, so I created CoreRemoting to have a migration path to .NET 5.

Any chances you could sketch up a new transport layer for Zyan based on CoreRemoting?

Yes. I would like to do the following:

  • Create a branch of Zyan code base
  • Set build target to .NET Standard 2.0 (so it will work for .NET Framework 4.7x+ and .NET Core / .NET 5)
  • Replace classic .NET Remoting calls with CoreRemoting calls
  • Remove ProtocolSetup implementations that are based on .NET Remoting
  • Create new WebSocket ProtocolSetup based on CoreRemoting
  • Use existing CoreRemoting functionality where possible to prevent double implementations (e.G. remote delegate support)

I'll try to make as few compatibility breaks as possible.
.NET Standard 2.0 will make migrations to the new branch more soft, because users of Zyan can migrate while still compile against .NET Framework 4.7x+.

I remember in the past you once made a working proof-of-concept WCF-based transport for Zyan.

WCF is also deprecated, so this is a dead end.

Websocket-sharp based CoreRemoting is a good replacement for the TcpDuplexChannel, because it also supports duplex communication over one single connection (makes callbacks/push through firewalls possible). I've tried several Websocket libraries and choosed Websocket-sharp at the end, because it gave the most reliable results. My first approach for CoreRemoting was gRPC. It worked quite nice too, but I ran into issues, when I tried to use it with Blazor clients, because gRPC relies on native C++ DLLs (there is managed code only new variant of gRPC, but this one doesn't run on .NET Framework 4.x).
TLS / SSL is difficult when it comes to Linux, so I decided to implement message based encryption similar to Zyan TcpDuplexChanel.

When it comes to serialization I ended in using classic BinaryFormatter (with applying your extensions to make it more safe :) and DataContractSerializer (which was used in WCF as default). The latter was required to support Blazor clients, because Microsoft blocks BinaryFormatter usage in Blazor. I've tried almost other serialization libraies (Protobuf, MessagePack, JSON.NET, ...) I could find on nuget, but they all have some restrictions that they are not usable for a .NET Remoting replacement library.

To leave to door to other transport and serialization technologies open, I've made them pluggable in CoreRemoting.

@yallie
Copy link
Member

yallie commented Jan 28, 2021

It will soon be ready for production, after the following features are completed

Sounds exciting! :)
You're going to build message integrity right into the transport protocol?

I'm working on a .NET Remoting based projecs for many years which has more than 1.1 millon lines of code

Did you ever use Zyan in your company's projects?

I'll try to make as few compatibility breaks as possible.

Perhaps we could get rid of too many constructor overloads in Zyan classes :)
I believe they were written before C# supported default parameter values.
I kept them to ensure 100% backwards compatibility, but now it's going to be a major breaking change anyway.

WCF is also deprecated, so this is a dead end.

Sure, WCF is a dead end.
I mentioned it because I believe that fork had some different approach to plugging transport channels.
But I don't remember much details about it.

To leave to door to other transport and serialization technologies open,
I've made them pluggable in CoreRemoting.

That's great! It would be awesome to make them pluggable in Zyan itself.
If we don't serialize anything really weird like delegates, it should be possible.

@theRainbird
Copy link
Contributor Author

You're going to build message integrity right into the transport protocol?

I have to add only a Signature property to the WireMessage class.
OK, someone may say, that message integrity is a separate concern and should be implemented separately. But I want to keep the code as easy and lean as possible. SoC is important, but keep the complexity low is important too.

Did you ever use Zyan in your company's projects?

Unfortunately not 😭.
The main project is a large ERP application. It's development was started in the early 90s. So it's difficult to migrate the infrastructure to a new framework. There was never budget for that.
We currently use classic .NET Remoting. Since last year we're switched from standard TcpChannel to GenuineChannels (gtcp). This one is a masterpiece. But it is still .NET Remoting which is deprecated.
So CoreRemoting will open a migration path even for that old grown large application to .NET 5 (I believe, that .NET 6 will be out, before the migration really begins).

Perhaps we could get rid of too many constructor overloads in Zyan classes :)

Of course, the Zyan source code should be polished.
Currently I develop almost everything on Linux and using JetBrains RiderIDE. It has excellent code inspection and makes refactoring much more easy compared the Visual Studio (only my subjective opinion).

If we don't serialize anything really weird like delegates, it should be possible.

No, only parameters to call delegates are serialized.
The problems I had with most serializers are to serialize DataSets / DataTables. And not only current snapshots of them, but rather complete DiffGrams (to bring RowStates and original values over the wire).

@yallie
Copy link
Member

yallie commented Jan 31, 2021

Unfortunately not 😭.
The main project is a large ERP application. It's development was started in the early 90s. So it's difficult to migrate the infrastructure to a new framework. There was never budget for that.

Sounds familiar...
Although we started many new projects with Zyan, we never migrated our legacy Remoting apps to Zyan.

@zaksnet
Copy link

zaksnet commented Feb 8, 2021

Hey Guys!
Any estimates and projections of when and if this is going to happen?

@theRainbird
Copy link
Contributor Author

Precise estimates are difficult 🔮, because I'm doing this only in my free time 🍸.
Before I start to migrate Zyan from classic .NET Remoting to CoreRemoting, development of CoreRemoting must be completed. There are only few tasks left. You can track the progress on the Project Kanban board.
When that tasks are done, CoreRemoting is feature complete.
Then I'll start to migrate Zyan. I start with it as soon as possible, because everyone using .NET Remoting or Zyan is already searching for a replacement. If it take to long, most users will have found other solutions.

@theRainbird
Copy link
Contributor Author

First migration steps towards .NET 5 are done.
Basic Zyan RPC features are now running on .NET 5 with CoreRemoting under the hood.
Many things like events, delegates, InterLinq are not working yet.

This is the commit: 0aca4ad
You can find the CoreRemoting migration version at the following branch: https://github.com/zyanfx/Zyan/tree/with_coreremoting

@yallie
Copy link
Member

yallie commented Jun 30, 2021

That's great! 🎉

InterLinq probably just needs a new adaptor/query executor for the CoreRemoting.
I think that events and delegates will be the most tricky part...
As far as I remember, the current implementation relies on a special treatment for MarshalByRefObjects.

@theRainbird
Copy link
Contributor Author

CoreRemoting currently does support delegates and events, but not MarshalByRefObj. So I have implement this first in CoreRemoting.
MarshalByRefObj behavior is tricky to achieve on .NET Core / .NET 5, because there is no RealProxy implementation. So I'll using Castle.DynamicProxy. This one is great, but it can only proxy interfaces without limitations. When proxy a class, only virtual members could be intercepted.
Interface proxies should be enough to get Zyan event and delegate support running, but not enough to easily migrate classic .NET Remoting applications to CoreRemoting. Generating a wrapper with IL on runtime could be possible fallback solution.

My next steps will be:

  • Adding basic support for interface covered MarshalByRefObjects in CoreRemoting
  • Fix delegate and event support in Zyan
  • Fix InterLinq support in Zyan
  • Fix other Zyan features like call interception

@theRainbird theRainbird self-assigned this Jul 2, 2021
@yallie
Copy link
Member

yallie commented Jul 2, 2021

CoreRemoting currently does support delegates and events, but not MarshalByRefObj. So I have implement this first in CoreRemoting.

Do we really need MarshalByRefObj support?
It looks to me as an implementation details in Zyan, not a feature.
One of key points of Zyan is to avoid using MarshalByRefObjs and other .NET Remoting APIs.

This one is great, but it can only proxy interfaces without limitations. When proxy a class, only virtual members could be intercepted.

Zyan only supports proxies for interfaces, does it?

@theRainbird
Copy link
Contributor Author

But Zyan is using MarshalByRefObjects internally to provider delegate and event support.
So I have two options to get Zyan delegate and event support running on .NET 5:

  • Implement interface baked MarshalByRefObj on CoreRemoting (Zyan delegate / event logic then should work without many changes)
  • Rework the Zyan delegate and event support, so that it does no longer user MashalByRefObj internally (It can use delegates instead)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants