Language-ext 1.7 released!
Lots of things have been improved over the past 3 months, especially in the Process system, but in general also. Now feels like a good time to get a release out. Any problems, shout!
Core
- Added: Units of measure:
Length
,Velocity
,Acceleation
,Area
andTime
- Added:
List.span
- applied to a predicate and a list, returns a tuple where first element is longest prefix of elements that satisfy the predicate and second element is the remainder of the list. - Added:
List.tails
function - returns all final segments of the list argument, longest first. - Added: Applicative support for
Option
,OptionUnsafe
,Either
,EitherUnsafe
,Try
,TryOption
,List
,IEnumerable
(Prelude.apply
function orApply
extension method) - Added: Support for arithmetic operators on all monadic types with provision of
IAppendable
,ISubtractable
,IProductable
,IDivisible
andINumeric
. Allowing for operations like this:Some(10) + Some(10) == Some(30)
, andList(1,2,3) + List(4,5,6) == List(1,2,3,4,5,6)
- Added:
List.foldUntil
,List.foldWhile
- Added: Functional version of
using(...) { }
calleduse
- Added:
tryuse
which is a version of 'use' that returns aTry<T>
; whereT
is anIDisposable
- Added: Extension method:
Try<T>.Use()
, same astryuse
- Added:
Try<T>.IfFail(Exception ex => ...)
- Added:
Try<T>.IfFail().Match()
- allows matching ofException
types as a single expression
Tuple<A,B>
bi-functor, bi-foldable, bi-iterable
Tuple<A,B,C>
tri-functor, tri-foldable, tri-iterable - Added:
Serializable
attribute toEither
,EitherUnsafe
,Lst
,ListItem
,Map
,MapItem
,Option
,OptionUnsafe
,Que
,Stck
, - Moved
Prelude.init
,Prelude.initInfinite
,Prelude.repeat
toList
Process system
- Strategy system - Decalarative way of dealing with Process failure
- Match on exceptions and map to Directives (Stop, Restart, Resume, Escalate)
- Map the Directives to MessageDirectives to decided on the fate of the failed message (Send to dead letters, Send to self (front or back of the queue), Send to supervisor, Send to specified Process)
- Session system - Allows consuming code to set a session-ID that is propagated throughout the system with the messages. Very useful for hooking up to authentication systems.
- Roles. Each node in a cluster must specify a role name.
- Process.ClusterNodes property - Has a map of alive cluster nodes and their roles.
- Routers - Processes that can auto-route messages to child processes or a provided set of processes. Default routers include:
- Broadcast
- Round-robin
- Random
- Least-busy
- Dispatchers - Like routers but without an actual Process. Dispatchers have a sender specified list of Processes to dispatch to, i.e. Dispatch.leastBusy(pid1, pid2, pid3). There are four default dispatchers:
- Broadcast
- Round-robin
- Random
- Least-busy
Bespoke dispacthers can be registered using Dispatch.register(...)
- Role dispatchers - Using a combination of
Process.ClusterNodes
and dispatchers, the Role dispatchers allow for ProcessIds to be built that refer to locations in the cluster by role. ie.Role.Broadcast["mail-server"]["user"]["smtp"]
will create aProcessId
that looks like this:/disp/role-broadcast/user/smtp
. Because it's aProcessId
it can be used with any of the existing functionality that accepts ProcessIds (tell
,ask
,subscribe
, etc.) but it has a behaviour baked in (broadcast
in this case). So doing atell
will send to allsmtp
Processes in the cluster.
There are severalRole
dispatchers:Role.Broadcast
Role.RoundRobin
Role.Random
Role.LeastBusy
Role.First
Role.Second
Role.Third
Role.Last
- Death-watch system:
Process.watch
andProcess.unwatch
to get oneProcess
watching for the death of another. Separate inbox calledTerminated
is used so that your primary inboxes can stay strongly typed. Process
setup functions are invoked immediately, rather than on their first message.- More improvements to the F# API to bring it closer to parity with the C# API - this work is on-going.
- Process.js now has a Process.spawnView function (if knockout.js is in use) that allows for synchronisation of
Process
state and view state as well as hooking up event functions.
Breaking changes.
Hopefully very few. But areas to watch out for:
- Remove the old
with
functions that were deprecated a while ago because I needed them for a newmatch
by value and exception function. If you get errors around this area, you should usePrelude.map
instead. Cluster.connect
now expects an extra parameter. It is the role of the node in the cluster. You don't have to use roles, but you do have to give it a validProcessName
- F# Process system has had its Process ID type changed from
(unit -> ProcessId)
toProcessId
. It was a useful experiment for a while to avoid makingProcessFs.Self
andProcessFs.Sender
into functions; but has created friction between the C# and F# implementations ever since. So I have changed the F# API to use the sameProcessId
that the C# does and have changedProcessFs.Self
and the like to return 'special' ProcessIds (/__special__/self
for example) that are resolved on use. So you should also be careful if you ever need to send these special paths around to useresolvePID pid
to extract the actual path. This does mean thattell (Sender()) msg (Self())
can be writtentell Sender msg Self
, which I think is much more attractive and easy to deal with. So the occassionalresolvePID Self
I think is less of a problem.
Documentation
- There's more of it!
Thanks to @la-yumba and @Jagged for their help with this release.
Nu-get
As usual everything is release on NuGet:
- LanguageExt.Core - https://www.nuget.org/packages/LanguageExt/
- LanguageExt.Process - https://www.nuget.org/packages/LanguageExt.Process
- LanguageExt.Process.Redis - https://www.nuget.org/packages/LanguageExt.Process.Redis