Migration guide to 1.3.x
Closed this issue · 3 comments
The migration is not as bad as initial code red lines may show.
-
The static parameter of
UseOptionTypes
: bool changed toFSharp.Data.Sql.Common.NullableColumnType
enum where the items are listed below. For easiest migration just select value corresponding your old value.NO_OPTION
- old "false"OPTION
- old "true"VALUE_OPTION
- totally new option using voption type, which has benefits of option but with lighter weight object-capsuling.
-
Async changed to task. So basically if you don't want to migrate too much and used async before, just use
|> Async.AwaitTask
after each call. Later you can consider should you change your asyncs to tasks or not (i.e. are they just small operations (task) or workflows (async) with timeouts, cancellations, etc).
What was the rationale for number 2?
Async and task are designed from a bit separate point of view: Async is good when you have many complex parallel workflows. Task is good when you want to execute a small thing now. Task is performance-wise way more faster. Most of SQLProvider things are "please execute me this query now", so the new task computation fits to SQLProvider scenario better.
All the database drivers that SQLProvider is using, are using tasks. Most of the APIs that SQLProvider is used in, are also now task-based. So there was no point of converting task->async->task.
That been said I cannot blindly recommend converting everything to task. I'd say as a rule of thumb: if you have a function that is less than 30 F# lines, then convert it to task. But if you have functions over e.g. 150 lines capsulated to task, they probably will just break runtime unless you break them to multiple separate non-nested-functions, to keep your tasks small. So keep them as async and just do Async.AwaitTask
. Best indication is that if you compile in release mode and it gives you this warning warning FS3511: This state machine is not statically compilable. A resumable code invocation at '(...-...)' could not be reduced.
that means the task might not be working runtime as it should.
I prefer async for the usual reasons (especially just that it's easier to reason about), but I see why you did it, thanks for the great explanation.