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

Akka on .Net Core/PCL #992

Closed
ehaskins opened this issue May 19, 2015 · 38 comments
Closed

Akka on .Net Core/PCL #992

ehaskins opened this issue May 19, 2015 · 38 comments

Comments

@ehaskins
Copy link

I'm interested in running Akka.net on .Net Core in ASP.net vNext. That currently isn't supported, but it doesn't look like it'd be insurmountable to make Akka's core a PCL.

  • Using System.Configuration - Could this be extracted into a separate library?
  • Using IClonable - Some precompiler statements should resolve that
  • Using System.Runtime.Serialization namespace
  • Using System.Runtime.Remoting namespace

I've only spent about an hour looking at this, so I'm probably missing something harder, but has anyone given this more serious thought or consideration?

@Aaronontheweb
Copy link
Member

@ehaskins I haven't given this much thought - this is the second or third time it's come up though.

Using System.Configuration - Could this be extracted into a separate library?

What we really use this for is automatically loading Akka.NET configuration automatically from App.config / Web.config. Removing this into its own separate library would be a major breaking change to today's API. Everyone's apps would still "run," but without their configuration - it's actually the worse kind of breaking change: the "fails at runtime" type.

As for the other stuff, I'm sure we could refactor our usage of ICloneable and I'm not sure if we even need those other two namespaces.

@rogeralsing
Copy link
Contributor

System.Runtime.Serialization is used in our exception types, they have ctors using SerializationInfo
System.Runtime.Remoting is used in the async await task scheduler

ICloneable could probably be removed, only Address uses it

@nvivo
Copy link
Contributor

nvivo commented May 20, 2015

.NET Core needs to be considered a new "target" for compilation, and this will require some changes. If you look into the CoreFx repo, there is a lot of "#ifdefs" to compile things differently for .NET Core vs .NET. It's a similar but different API.

  • System.Configuration - won't be required as .NET Core can load hocon files directly with an "UseHoconConfig()" extension
  • System.Runtime.Remoting - I doubt this will be a requirement from CallContext on .NET Core, it may simply not be a dependency there

Most things can be solved by "ifdefs". But .NET Core is probably a year away, and doing this at this time in the "dev" branch is very uncertain. They said they are still deciding if more libraries will be ported.

Someone could try on a personal branch to see what would take.

@adamhathcock
Copy link
Contributor

Is there a feature branch started? I'd like to look at it and help as this is of interest to me as well.

@nvivo
Copy link
Contributor

nvivo commented May 21, 2015

@adamhathcock

I don't think there is a branch for that yet, otherwise @Aaronontheweb would have mentioned it. Right now, the best thing for you is to fork and create your own experimental branch to see where it goes.

Once you have something, create a PR for analysis. Since this is a new target, I guess it will take time and lots of feedback before it gets merged. But it needs to start somewhere.

@adamhathcock
Copy link
Contributor

I guess I was hoping @ehaskins had one or something. I wouldn't be sure what to do about the multi-project setup as VS2015 has xproj now for targetting .NET Core.

I just haven't done enough reading about best practices for all the next gen project setup. I got something attempting builds but it felt ugly.

@rogeralsing
Copy link
Contributor

We discussed this yesterday and we in the core team is not going to involve ourselves in this_right now_, as this is not where our main user base is focused and the effort will distract us from finishing more important tasks.

That being said, if anyone is willing to give this a try, please do so

@Aaronontheweb
Copy link
Member

@rogeralsing beat me to the punch!

One day in the future, this might make a lot of sense for our users - but that's not where they are today. Hell, judging from the volume of "do you support .NET 4.0?" questions we get we're still considered to be bleeding edge in some circles by being .NET 4.5-only.

That being said, I would love to see a prototype of this in someone's fork as I'm personally interested in using it myself.

@ehaskins
Copy link
Author

@adamhathcock @adamhathcock All I've done so far, is convert the Akka project to a PCL to see how many compile errors I'd get. Feel free to take a look at it in the PCL branch of my fork. I hadn't decided if I'll have the time to tackle this.

@adamhathcock
Copy link
Contributor

I've made my own branch and I got HelloAkka to work:
https://github.com/akkadotnet/akka.net/compare/dev...adamhathcock:coreclr?expand=1

.NET Core is still very much in flux but we're trying to use it anyway. I've used a pre-beta6 to get some more of the reflection classes in. VS 2015 RC defaults to beta4.

I'd like people just to glance at some of the things I had to do just to see if there might be something better or different. I think the most questionable thing is the removal of CallContext as I really didn't know what to do there besides try ThreadStatic.

@rogeralsing
Copy link
Contributor

@adamhathcock awesome! :)

Regarding CallContext, that one is tricky, the current design of the Akka.NET API will not be able to do async await support inside actors w/o the call context, so that would have to be removed in the PCL version.

@adamhathcock
Copy link
Contributor

Finally figured out how to execute unit tests. I'll think I'll leave it at there for now and wait for more beta milestones.

Hopefully, the CallContext thing is just not exposed yet. From my understanding, it's needed to move static state along with async/await and I don't know any other mechanism that would work.

@adamhathcock
Copy link
Contributor

By happenstance, I literally found in the answer just after typing my last comment. AsyncLocal in DNX replaces CallContext. Just updated the branch.

Okay, really trying not to overwhelm the discussion here :)

@nvivo
Copy link
Contributor

nvivo commented Jun 12, 2015

Funny that AsyncLocal seems to be available from .net 4.5 (at least msdn says so) , and I didn't see it before.

I didn't look into it yet, but I wonder why @StephenCleary didn't mention it when we asked him about options to flow context. Is this new or is this also being deprecated? If this is available in plain old .NET, maybe it's an option for the current flow issues.

@StephenCleary
Copy link

AsyncLocal is coming in 4.6 (it's not in 4.5). It's essentially a wrapper around the logical call context.

@nvivo
Copy link
Contributor

nvivo commented Jun 12, 2015

Thanks for the clarification @StephenCleary.

Right, at MSDN (https://msdn.microsoft.com/en-us/library/dn906268(v=vs.110).aspx), the top of the page says both 4.5 and 4.6, but at the bottom it says only 4.6. That's why I was confused, only looked at the top.

@adamhathcock
Copy link
Contributor

I've updated the DNX usage to beta6. I haven't attempted anything hard like Remote.

Targets are now .NET 4.5, DNX .NET 4.5.1 and DNX .NET CORE 5.0. Tests pass and the HelloWorld and FaultTolerance samples work.

@rogeralsing
Copy link
Contributor

Awesome! 👍

@adamhathcock
Copy link
Contributor

I'd like to keep this up. Have you guys considered moving to xproj? You can still target net 4.5 as well as dnx. The downsides are the you can't reference a xproj from a csproj (this will be fixed) nor build a non-dnx executable. Just DLLs.

I guess those are two big downsides currently :)

@adamhathcock
Copy link
Contributor

Updated again to beta 7.

Need to get a Net Core version of Wire and Helios to really dive deeper.

@adamhathcock
Copy link
Contributor

Another issue: Type.GetType() (e.g. used for loading a logging actor) only works for the current executing assembly. Need to redo this.

Hopefully #1263 is still on the cards (soon :) )

@rogeralsing
Copy link
Contributor

@adamhathcock huh, Type.GetType does not accept fully qualified type names (that are not yet loaded)?

@adamhathcock
Copy link
Contributor

Under DNX, there aren't necessarily Assemblies and no AppDomains. From my understanding, the static Assembly methods only really works for the current project. Certain Assembly methods just don't work either. I'm guessing Type.GetType(string) under DNX only will find types in the current (or maybe just the entry) project.

To find all loaded types, usage of ILibraryManager (https://github.com/aspnet/dnx/blob/master/src/Microsoft.Dnx.Runtime.Abstractions/ILibraryManager.cs) is how you do it. Looks like they've abstracted the concept of Assemblies and Projects behind the Library object.

You can get it either dependency injected or statically use CallContextServiceLocator to get the IServiceProvider and get it.

@nvivo
Copy link
Contributor

nvivo commented Oct 7, 2015

2 cents here...

I remember seeing some explanation on a community standup about this. It seems the task of locating assemblies was moved out of the runtime into DNX, because it may need to locate a package in another folder or compile from source. In the end, assemblies still exist at runtime, but the runtime acts more as "read only". Type.GetType probably sees whatever was passed by DNX, but doesn't cause anything to load if it isn't.

If needed, it seems there is a way to load assemblies later, but as a explicit call, so in theory the behavior could be replicated. I couldn't figure out if this is the expected way to do it or how exactly to call it. Maybe stackoverflow or an issue on their repo could answer the proper way to do this.

@adamhathcock
Copy link
Contributor

The logger I tested definitely was in an assembly that was used. It just wasn't in the entry assembly. Type.GetType didn't work for anything in that assembly (in my watch window) but it did for the entry assembly. I stopped there knowing several of the Assembly.Get* methods (Entry, Executing) don't work but GetCurrent does work.

I guess I need to test it further. In my own code, I don't load types or assemblies except from ILibraryManager because of things I've run into. Maybe it will be more clear when they start documenting :)

@nvivo
Copy link
Contributor

nvivo commented Oct 7, 2015

If you're adding a logger as usual, putting the assembly side by side in the same folder, it won't be loaded automatically by .NET. Only explicit dependencies are loaded, that is, the ones the compiler adds to the IL manifest. If I'm not mistaken (may be wrong here), even today, csc filters out from the manifest references you have but don't actually use.

So, DNX won't load them automatically just because they're in the same folder.

See if this custom loader helps: aspnet/dnx#1412

@adamhathcock
Copy link
Contributor

This is an explicit dependency. The second assembly has code being used by the entry assembly. It ought to show in ILibraryManager but Type.GetType didn't work.

I'll do some more explicit testing tomorrow my time and get back to you.

@adamhathcock
Copy link
Contributor

I did a test repo: https://github.com/adamhathcock/dnx-test/blob/master/src/ConsoleApp1/Program.cs

Type.GetType doesn't work. If I get the Assembly object, Assembly.GetType doesn't work. If I do Assembly.GetTypes then the type is in the list.

@adamhathcock
Copy link
Contributor

Just realized I did something dumb. Assembly.GetType(string) does work. Type.GetType(string) doesn't

@ronnyek
Copy link

ronnyek commented Nov 25, 2015

Now that api's are stabilizing with recent rc1 release, has anyone played with this any more? I'm very interested to see how much of akka is gonna run on core clr. I can run monoruntime for now, but I'd really be interested in real coreclr support.

@Aaronontheweb
Copy link
Member

Since there's still a lot of healthy discussion on here, going to re-open this up as part of an ongoing conversation

@Aaronontheweb Aaronontheweb reopened this Nov 25, 2015
@adamhathcock
Copy link
Contributor

Just updated my branch again to RC1 and latest Dev: https://github.com/akkadotnet/akka.net/compare/dev...adamhathcock:coreclr?expand=1

Everything seems fine. I haven't addressed the logging thing but I know Type.GetType() works now. I'd like to use Wire but that's not NETCore'd yet. I haven't attempted to target any of the "standard" targets introduced in RC1 (and will change names in RC2)

Just a screenshot to show what I've ported. I'd like to contribute to an official branch.

image

@adamhathcock
Copy link
Contributor

Now just updating against master: https://github.com/akkadotnet/akka.net/compare/master...adamhathcock:coreclr?expand=1

I want to do Akka.Remote but it will involve understanding Google.ProtocolBuffers and the new version Google.Protobuf (which is 3.0 beta and supports NET Core) but that seems daunting to me at the moment.

@newmancodes
Copy link

I would also be extremely interested in this being a possibility.

@adamhathcock
Copy link
Contributor

Updated my branch to 1.0.6 with some minor fixes.

Working on building this internal to my company to use on .NET Core on some projects we've got.

@Neftedollar
Copy link

@adamhathcock thank you, Adam.

@lnaie
Copy link

lnaie commented Apr 24, 2016

Actually it would be great to have something as akka fully or partially ready when dotnet core goes live.

@marcpiechura
Copy link
Contributor

Working on it, see #2153

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

No branches or pull requests