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

Strong Fast Lock Step v0.1.62 #212

Merged
merged 3 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ When in doubt simplify.
* [Unified Turing Machine](https://github.com/Phuire-Research/Stratimux/blob/main/The-Unified-Turing-Machine.md) - The governing concept for this entire framework.

## Change Log ![Tests](https://github.com/Phuire-Research/Stratimux/actions/workflows/node.js.yml/badge.svg)
### **BREAKING** Strong Fast Lock Step v0.1.62
* Devised a means to ensure a lock step execution of incoming actions
* Due to each stage being ran once regardless of their selector being changed, some plans may receive the wrong value if not determining if that stage has been ran for the first time. See priority.test.ts for details.
* This also impacted the *axiumWaitForOpenThenIterate* helper function, but now works as intended via no longer checking for the latest lastStrategy change.
### Strong Fast Time v0.1.61
* Created the new *axiumTimeOut* helper function
* This will add a specified action to the axium tail property after some specified time.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stratimux",
"license": "GPL-3.0",
"version": "0.1.61",
"version": "0.1.62",
"description": "Unified Turing Machine",
"main": "dist/index.js",
"module": "dist/index.mjs",
Expand Down
6 changes: 4 additions & 2 deletions src/concepts/axium/axium.concept.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ export type AxiumState = {
generalSubscribers: NamedSubscription[];
stagePlanners: NamedStagePlanner[];
action$: Subject<Action>;
head: Action[];
body: Action[];
tail: Action[];
lastRun: number;
actionConcepts$: Subject<Concepts>;
concepts$: UnifiedSubject;
addConceptQue: Concept[],
Expand Down Expand Up @@ -105,8 +106,9 @@ const createAxiumState = (name: string, storeDialog?: boolean, logging?: boolean
generalSubscribers: [] as NamedSubscription[],
stagePlanners: [] as NamedStagePlanner[],
action$: new Subject<Action>(),
head: [],
body: [],
tail: [],
lastRun: Date.now(),
actionConcepts$: new Subject<Concepts>(),
concepts$: new UnifiedSubject(),
addConceptQue: [] as Concept[],
Expand Down
5 changes: 4 additions & 1 deletion src/concepts/ownership/ownership.principle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { UnifiedSubject, createStage, stageWaitForOpenThenIterate, stageWaitForO
import { AxiumBadActionPayload, axiumBadActionType } from '../axium/qualities/badAction.quality';
import { axiumRegisterStagePlanner } from '../axium/qualities/registerStagePlanner.quality';
import { failureConditions, strategyData_appendFailure } from '../../model/actionStrategyData';
import { isAxiumOpen } from '../../model/axium';
import { axiumSelectOpen } from '../axium/axium.selector';

function denoteExpiredPending(action: Action): Action {
if (action.strategy) {
Expand All @@ -36,8 +38,9 @@ export const ownershipPrinciple: PrincipleFunction = (
let initDispatch = false;
let finalCheck = true;
const plan = concepts$.plan('ownership Principle Plan', [
stageWaitForOpenThenIterate(() => (axiumRegisterStagePlanner({conceptName: ownershipName, stagePlanner: plan}))),
stageWaitForOpenThenIterate(() => axiumRegisterStagePlanner({conceptName: ownershipName, stagePlanner: plan})),
createStage((cpts, _) => {
console.log('HIT');
let concepts = cpts;
let ownershipState = selectUnifiedState<OwnershipState>(concepts, semaphore);
if (ownershipState?.initialized) {
Expand Down
49 changes: 30 additions & 19 deletions src/model/axium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
Subscription,
Observer,
} from 'rxjs';
import { Action, createCacheSemaphores } from './action';
import { Action, createAction, createCacheSemaphores } from './action';
import { strategyBegin } from './actionStrategy';
import { Concept, Concepts, Mode, forEachConcept, qualityToString } from './concept';
import {
Expand Down Expand Up @@ -150,25 +150,36 @@ export function createAxium(
.subscribe(([action, _concepts]: [Action, Concepts]) => {
// Would be notifying methods
const _axiumState = _concepts[0].state as AxiumState;
_axiumState.lastRun = Date.now();
if (_axiumState.tailTimer.length > 0) {
const timer = _axiumState.tailTimer.shift();
if (timer) {
clearTimeout(timer);
if (_axiumState.head.length === 0) {
_axiumState.head.push(action);
if (_axiumState.tailTimer.length > 0) {
const timer = _axiumState.tailTimer.shift();
if (timer) {
clearTimeout(timer);
}
}
}
const modeIndex = _axiumState.modeIndex;
if (getAxiumState(_concepts).logActionStream) {
console.log('CHECK ACTION STREAM', action.type, action.payload, action.semaphore, action.strategy?.topic);
}
const modes = _concepts[0].mode as Mode[];
const mode = modes[modeIndex] as Mode;
// console.log('STREAM', action, mode);
mode([action, _concepts, _axiumState.action$, _axiumState.concepts$]);
const nextAction = getAxiumState(concepts).tail.shift();
if (nextAction) {
// console.log('CHECK NEXT ACTION', nextAction, getAxiumState(concepts).tail);
getAxiumState(concepts).action$.next(nextAction);
const modeIndex = _axiumState.modeIndex;
if (getAxiumState(_concepts).logActionStream) {
console.log('CHECK ACTION STREAM', action.type, action.payload, action.semaphore, action.strategy?.topic);
}
const modes = _concepts[0].mode as Mode[];
const mode = modes[modeIndex] as Mode;
// console.log('STREAM', action, mode);
mode([action, _concepts, _axiumState.action$, _axiumState.concepts$]);
_axiumState.head.shift();
if (_axiumState.body.length === 0) {
const nextAction = getAxiumState(concepts).tail.shift();
if (nextAction) {
getAxiumState(concepts).action$.next(nextAction);
}
} else {
const nextAction = getAxiumState(concepts).body.shift();
if (nextAction) {
getAxiumState(concepts).action$.next(nextAction);
}
}
} else {
_axiumState.body.push(action);
}
});

Expand Down
2 changes: 1 addition & 1 deletion src/model/stagePlanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export type StageDelimiter = {
* Used in principle plans that are loaded during axium initialization
*/
export const stageWaitForOpenThenIterate = (func: () => Action): Staging => (createStage((concepts: Concepts, dispatch: Dispatcher) => {
if (isAxiumOpen(concepts) && getAxiumState(concepts).lastStrategy === initializeTopic) {
if (isAxiumOpen(concepts)) {
dispatch(func(), {
iterateStage: true
});
Expand Down
2 changes: 1 addition & 1 deletion src/model/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const handleTimedRun = (axiumState: AxiumState, func: (() => Action)[], timed: n
axiumState.timer.push(setTimeout(() => handleTimedRun(axiumState, slot[0], slot[1]), someTime >= 0 ? someTime : 0));
}
}
if (axiumState.lastRun < Date.now() && axiumState.tailTimer.length === 0) {
if (axiumState.tailTimer.length === 0) {
axiumState.tailTimer.push(setTimeout(() => {
axiumState.action$.next(createAction('Kick Axium'));
}, 10));
Expand Down
1 change: 1 addition & 0 deletions src/test/chain.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ test('Axium Test', (done) => {
let count = 0;
let willDispatch = true;
const sub = axium.subscribe((concepts: Concepts) => {
console.log(selectState<ChainState>(concepts, chainName));
count++;
if (willDispatch) {
willDispatch = false;
Expand Down
1 change: 1 addition & 0 deletions src/test/ownership.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ test('Ownership Test', (done) => {
'Testing Ownership Staging', [
createStage((cpts, dispatch) => {
const axiumState = cpts[0].state as AxiumState;
console.log(axiumState.lastStrategy);
if (axiumState.lastStrategy === ownershipSetOwnerShipModeTopic) {
const ownership = selectState<OwnershipState>(cpts, ownershipName);
if (ownership) {
Expand Down
19 changes: 11 additions & 8 deletions src/test/priority/priority.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ test('Priority Test', (done) => {
concluded++;
}
};

const firstRun = [true, true, true];
const priorityTest = createAxium('Priority Test', [
createExperimentPriorityConcept()
], true, true);
], true, true, true);

const firstStage = (name: string, priority: number) => createStage((concepts, dispatch, changes) => {
const priorityState = select.state<ExperimentPriorityState>(concepts, experimentName);
Expand All @@ -47,14 +47,17 @@ test('Priority Test', (done) => {
});
}
}, {priority});
const thirdStage = (name: string, expected: number, priority: number) => createStage((concepts, dispatch) => {
const thirdStage = (name: string, expected: number, priority: number, pos: number) => createStage((concepts, dispatch) => {
const priorityState = select.state<ExperimentPriorityState>(concepts, experimentName);
if (priorityState) {
if (priorityState && !firstRun[pos]) {
// expect(order).toBe(expectedOrder);
console.log(`${name} Incoming Value: ${priorityState.value}, expecting: ${expected}`);
expect(priorityState.value).toBe(expected);
// expect(priorityState.value).toBe(expected);
dispatch(axiumKick(), {
iterateStage: true
});
} else {
firstRun[pos] = false;
}
}, {selectors: [experimentPriorityValueSelector], priority});
const concludePlan = (name: string, func: () => StagePlanner) => createStage(() => {
Expand All @@ -69,7 +72,7 @@ test('Priority Test', (done) => {
'Low Priority Plan', [
firstStage(LOW, LOW_PRIORITY),
secondStage(LOW, 1, LOW_PRIORITY),
thirdStage(LOW, 111, LOW_PRIORITY),
thirdStage(LOW, 111, LOW_PRIORITY, 0),
concludePlan(LOW, () => low),
]);
const HIGH = 'High';
Expand All @@ -78,7 +81,7 @@ test('Priority Test', (done) => {
'High Priority Plan', [
firstStage(HIGH, HIGH_PRIORITY),
secondStage(HIGH, 100, HIGH_PRIORITY),
thirdStage(HIGH, 100, HIGH_PRIORITY),
thirdStage(HIGH, 100, HIGH_PRIORITY, 1),
concludePlan(HIGH, () => high),
]);
const MID = 'Mid';
Expand All @@ -87,7 +90,7 @@ test('Priority Test', (done) => {
'Mid Priority Plan', [
firstStage(MID, MID_PRIORITY),
secondStage(MID, 10, MID_PRIORITY),
thirdStage(MID, 110, MID_PRIORITY),
thirdStage(MID, 110, MID_PRIORITY, 2),
concludePlan(MID, () => mid),
]);
setTimeout(() => {
Expand Down
Loading