Skip to content

General errors #177

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

Closed
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
aa162d2
CHG: Fibers enter WAITING state after an async result is received.
eric-corumdigital Feb 5, 2019
37a9af9
FIX
eric-corumdigital Feb 5, 2019
1c41cee
FIX
eric-corumdigital Feb 5, 2019
f2d414b
FIX
eric-corumdigital Feb 5, 2019
24d2568
FIX
eric-corumdigital Feb 5, 2019
206f3b9
FIX
eric-corumdigital Feb 5, 2019
bccb409
FIX: Fixed memory leak on V8
eric-corumdigital Feb 7, 2019
127fd21
CHG: trying something other than setTimeout to fix V8 memory leak
eric-corumdigital Feb 7, 2019
e03b941
FIX: Memory leak in V8 caused by new Error object
eric-corumdigital Feb 8, 2019
38fa57a
CHG: Simplified case ASYNC state.
eric-corumdigital Feb 8, 2019
3601775
FIX: moved two more Error instantiations outside of Aff.
eric-corumdigital May 13, 2019
a99e896
FIX: added error back to exports, fixed compile error
eric-corumdigital May 13, 2019
2f4b9a5
CHG: Generalised Aff for arbitrary error types; not backwards
eric-corumdigital Aug 3, 2019
aa68070
CHG: Moved generalised error implementation; put a better
eric-corumdigital Aug 27, 2019
ba47609
ADD: Observable Fiber status.
eric-corumdigital Aug 28, 2019
9899ce3
ADD: Explicit panics ADD: Bifunctor instance for Aff
eric-corumdigital Aug 30, 2019
a2f1049
FIX: imported wrong Error
eric-corumdigital Sep 6, 2019
648870d
ADD: Free Newtype conversions for Bifunctors.
eric-corumdigital Sep 6, 2019
c7d9b74
ADD: Type-proxied versions of free Bifunctor Newtype conversions.
eric-corumdigital Sep 6, 2019
18d7621
CHG: Use newtype constructor to type hint rather than Proxy.
eric-corumdigital Sep 6, 2019
09223d4
WIP FIX: joining on interrupted Fibers must panic.
eric-corumdigital Sep 9, 2019
7eb007e
FIX: unsafeFromSucceeded Interrupt error
eric-corumdigital Sep 10, 2019
0d7c02c
FIX: Supervisor leaks memory by not unregistering Fibers in COMPLETE
eric-corumdigital Sep 11, 2019
9e1e64b
Merge branch 'fix_supervisor_leak' of github.com:eric-corumdigital/pu…
eric-corumdigital Sep 11, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 114 additions & 42 deletions src/Effect/Aff.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ var Aff = function () {
An awkward approximation. We elide evidence we would otherwise need in PS for
efficiency sake.

data Aff eff a
data Aff e a
= Pure a
| Throw Error
| Catch (Aff eff a) (Error -> Aff eff a)
| Sync (Eff eff a)
| Throw e
| Catch (Aff e a) (e -> Aff e a)
| Sync (Effect a)
| SyncEither (Effect (Either e a))
| SyncUnsafe (Effect a)
| Async ((Either Error a -> Eff eff Unit) -> Eff eff (Canceler eff))
| forall b. Bind (Aff eff b) (b -> Aff eff a)
| forall b. Bracket (Aff eff b) (BracketConditions eff b) (b -> Aff eff a)
Expand All @@ -27,6 +29,8 @@ var Aff = function () {
var THROW = "Throw";
var CATCH = "Catch";
var SYNC = "Sync";
var SYNC_EITHER = "SyncEither"
var SYNC_UNSAFE = "SyncUnsafe"
var ASYNC = "Async";
var BIND = "Bind";
var BRACKET = "Bracket";
Expand Down Expand Up @@ -56,16 +60,19 @@ var Aff = function () {
var FIBER = "Fiber"; // Actual fiber reference
var THUNK = "Thunk"; // Primed effect, ready to invoke

function Aff(tag, _1, _2, _3) {
var early = new Error("[ParAff] Early exit");

function Aff(tag, _1, _2, _3, extra) {
this.tag = tag;
this._1 = _1;
this._2 = _2;
this._3 = _3;
this.extra = extra;
}

function AffCtr(tag) {
var fn = function (_1, _2, _3) {
return new Aff(tag, _1, _2, _3);
var fn = function (_1, _2, _3, extra) {
return new Aff(tag, _1, _2, _3, extra);
};
fn.tag = tag;
return fn;
Expand All @@ -85,14 +92,6 @@ var Aff = function () {
}
}

function runSync(left, right, eff) {
try {
return right(eff());
} catch (error) {
return left(error);
}
}

function runAsync(left, eff, k) {
try {
return eff(k)();
Expand All @@ -102,6 +101,15 @@ var Aff = function () {
}
}

function errorFromVal(x) {
if (x instanceof Error) {
return x;
}
else {
return new Error(x+'');
}
}

var Scheduler = function () {
var limit = 1024;
var size = 0;
Expand Down Expand Up @@ -313,31 +321,86 @@ var Aff = function () {
}
break;

// If the Effect throws, die.
// Otherwise, return the result.
case SYNC:
status = STEP_RESULT;
step = runSync(util.left, util.right, step._1);
try {
status = STEP_RESULT;
step = util.right(step._1());
} catch (error) {
interrupt = util.left(errorFromVal(error));
if (bracketCount === 0) {
status = RETURN;
step = null;
fail = null;
}
}
break;

// If the Effect throws, die.
// Otherwise, map Lefts to errors and Rights to returns.
case SYNC_EITHER:
try {
status = STEP_RESULT;
step = step._1();
} catch (error) {
interrupt = util.left(errorFromVal(error));
if (bracketCount === 0) {
status = RETURN;
step = null;
fail = null;
}
}
break;

// If the Effect throws, send to the error channel.
// Otherwise, return the result.
case SYNC_UNSAFE:
status = STEP_RESULT;
try {
step = util.right(step._1());
} catch (error) {
step = util.left(error);
}
break;

case ASYNC:
status = PENDING;
step = runAsync(util.left, step._1, function (result) {
return function () {
if (runTick !== localRunTick) {
return;
}
runTick++;
Scheduler.enqueue(function () {
// It's possible to interrupt the fiber between enqueuing and
// resuming, so we need to check that the runTick is still
// valid.
if (runTick !== localRunTick + 1) {
tmp = step._1;
step = nonCanceler;
Scheduler.enqueue(function () {
if (runTick !== localRunTick) {
return;
}
var skipRun = true;
var canceler = runAsync(util.left, tmp, function (result) {
return function () {
if (runTick !== localRunTick) {
return;
}
++runTick;
status = STEP_RESULT;
step = result;
run(runTick);
});
};
step = result;
// Do not recurse on run if we are synchronous with runAsync.
if (skipRun) {
skipRun = false;
} else {
run(runTick);
}
};
});
// Only update the canceler if the asynchronous action has not
// resolved synchronously. If it has, then the next status and
// step have already been set.
if (skipRun) {
step = canceler;
skipRun = false;
}
// If runAsync already resolved then the next step needs to be
// run.
else {
run(runTick);
}
});
return;

Expand Down Expand Up @@ -643,9 +706,6 @@ var Aff = function () {
var killId = 0;
var kills = {};

// Error used for early cancelation on Alt branches.
var early = new Error("[ParAff] Early exit");

// Error used to kill the entire tree.
var interrupt = null;

Expand Down Expand Up @@ -808,10 +868,14 @@ var Aff = function () {
if (lhs === EMPTY && util.isLeft(rhs) || rhs === EMPTY && util.isLeft(lhs)) {
return;
}
// If both sides resolve with an error, we should continue with the
// first error
// If both sides resolve with an error, continue with the errors
// appended in order.
if (lhs !== EMPTY && util.isLeft(lhs) && rhs !== EMPTY && util.isLeft(rhs)) {
fail = step === lhs ? rhs : lhs;
fail = util.left(
step === lhs
? head.extra(util.fromLeft(rhs))(util.fromLeft(lhs))
: head.extra(util.fromLeft(lhs))(util.fromLeft(rhs))
);
step = null;
head._3 = fail;
} else {
Expand Down Expand Up @@ -898,7 +962,7 @@ var Aff = function () {
if (head) {
tail = new Aff(CONS, head, tail);
}
head = new Aff(ALT, EMPTY, step._2, EMPTY);
head = new Aff(ALT, EMPTY, step._2, EMPTY, step.extra);
step = step._1;
break;
default:
Expand Down Expand Up @@ -1011,6 +1075,8 @@ var Aff = function () {
Aff.Throw = AffCtr(THROW);
Aff.Catch = AffCtr(CATCH);
Aff.Sync = AffCtr(SYNC);
Aff.SyncEither = AffCtr(SYNC_EITHER);
Aff.SyncUnsafe = AffCtr(SYNC_UNSAFE);
Aff.Async = AffCtr(ASYNC);
Aff.Bind = AffCtr(BIND);
Aff.Bracket = AffCtr(BRACKET);
Expand Down Expand Up @@ -1063,6 +1129,10 @@ exports._fork = function (immediate) {

exports._liftEffect = Aff.Sync;

exports._liftEffectEither = Aff.SyncEither;

exports._liftEffectUnsafe = Aff.SyncUnsafe;

exports._parAffMap = function (f) {
return function (aff) {
return Aff.ParMap(f, aff);
Expand All @@ -1075,9 +1145,11 @@ exports._parAffApply = function (aff1) {
};
};

exports._parAffAlt = function (aff1) {
return function (aff2) {
return Aff.ParAlt(aff1, aff2);
exports._parAffAlt = function (append) {
return function (aff1) {
return function (aff2) {
return Aff.ParAlt(aff1, aff2, null, append);
};
};
};

Expand Down
Loading