Skip to content
This repository has been archived by the owner on Feb 3, 2023. It is now read-only.

riker for hash table #226

Merged
merged 57 commits into from
Aug 30, 2018
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
12135ce
WIP on riker actor
thedavidmeister Aug 11, 2018
edb2676
passing tests with symlinked riker config
thedavidmeister Aug 11, 2018
1480a6c
WIP on riker actors for chain
thedavidmeister Aug 11, 2018
c762be3
Merge commit 'dbe3762feb134ed97c8383ae89f56ec396d95f64' into 135-riker
thedavidmeister Aug 15, 2018
ffff40b
WIP on porting hash table to riker
thedavidmeister Aug 15, 2018
9792714
wip on porting hashtable to actor
thedavidmeister Aug 15, 2018
a66a0df
Merge commit '71c2841ffd5944f2cd4e9395c189b6a3c6fee372' into 135-riker
thedavidmeister Aug 15, 2018
7431b71
WIP on splitting out chain actor
thedavidmeister Aug 15, 2018
4842d8b
WIP on SourceChain trait
thedavidmeister Aug 16, 2018
db5beba
WIP on chain and hash table actors
thedavidmeister Aug 16, 2018
e5e694d
WIP on nested executors for actors
thedavidmeister Aug 18, 2018
2f7b650
one sys for riker spike
thedavidmeister Aug 18, 2018
abb7312
passing round trip through the hash table with an actor
thedavidmeister Aug 18, 2018
e441119
fixing tests
thedavidmeister Aug 19, 2018
569541c
move actor system into hash table
thedavidmeister Aug 19, 2018
39c0e66
lint
thedavidmeister Aug 19, 2018
c1d922f
lint
thedavidmeister Aug 19, 2018
8605b34
lint
thedavidmeister Aug 19, 2018
5cefae0
fmt
thedavidmeister Aug 19, 2018
0f44ca1
Merge branch 'develop' into 135-riker-one-sys
thedavidmeister Aug 19, 2018
dcab700
test for hash table round trip in threads
thedavidmeister Aug 20, 2018
cb8324e
pass the test pair through the channel for the round trip
thedavidmeister Aug 20, 2018
13d010b
fmt
thedavidmeister Aug 20, 2018
fa8ef92
WIP on clone safety for chain
thedavidmeister Aug 20, 2018
ba096fc
WIP with debug on actors hanging
thedavidmeister Aug 21, 2018
c21b221
Merge commit '19cc38ab71293497f87b13f764c9d5940786436d' into 135-rike…
thedavidmeister Aug 28, 2018
0ce3251
WIP on merge cleanup
thedavidmeister Aug 28, 2018
e38c4a0
remove riker config
thedavidmeister Aug 28, 2018
4145a22
remove broken symlink
thedavidmeister Aug 28, 2018
938c41a
documentation for actor.rs
thedavidmeister Aug 28, 2018
9824d0b
lint
thedavidmeister Aug 28, 2018
2041b1f
return reference to chain from agent state
thedavidmeister Aug 28, 2018
17e2942
lint docs
thedavidmeister Aug 28, 2018
ad248c0
rename ask to block_on_ask
thedavidmeister Aug 28, 2018
4c4f041
test chain actor round trip
thedavidmeister Aug 28, 2018
c0d1820
remove Get in protocol variant names
thedavidmeister Aug 28, 2018
86abfe9
fix compiler issues
thedavidmeister Aug 28, 2018
eb172a1
polish for PR
thedavidmeister Aug 28, 2018
9b66a68
remove broken symlink
thedavidmeister Aug 28, 2018
f5636d6
lint
thedavidmeister Aug 28, 2018
d464a02
lint
thedavidmeister Aug 28, 2018
9d4f37c
lint docs
thedavidmeister Aug 28, 2018
9bb98ea
lint docs
thedavidmeister Aug 28, 2018
e1e4635
lint docs
thedavidmeister Aug 28, 2018
a1a4a34
fmt
thedavidmeister Aug 28, 2018
a42fd91
lint ns
thedavidmeister Aug 28, 2018
0b5a31b
fix non-deterministic test
thedavidmeister Aug 28, 2018
285da2a
lint docs
thedavidmeister Aug 28, 2018
417ed51
fmt
thedavidmeister Aug 28, 2018
ca163dd
lint docs
thedavidmeister Aug 28, 2018
23213e5
Merge branch 'develop' into 135-riker-one-sys
thedavidmeister Aug 29, 2018
d33cf90
working stress test for actor round trip
thedavidmeister Aug 30, 2018
78462da
Merge branch '135-riker-one-sys' of github.com:holochain/holochain-ru…
thedavidmeister Aug 30, 2018
15f7b8a
Merge commit '03f7de11ffa0a4d5a570cc2a824340385c0f5d22' into 135-rike…
thedavidmeister Aug 30, 2018
64ed52a
fmt
thedavidmeister Aug 30, 2018
a83b4c4
basic mdbook docs for actors and hash table
thedavidmeister Aug 30, 2018
d4dbbe7
Merge branch 'develop' into 135-riker-one-sys
thedavidmeister Aug 30, 2018
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
6 changes: 6 additions & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ multihash = "0.8.0"
rust-base58 = "0.0.4"
bitflags = "1.0"
holochain_wasm_utils = { path = "../wasm_utils"}
riker = "0.1.7"
riker-default = "0.1.7"
riker-patterns = "0.1.7"
futures-preview = "0.2.2"
lazy_static = "1.1.0"
unwrap_to = "0.1.0"
num-traits = "0.2"
num-derive = "0.2"
config = "0.8"

[dev-dependencies]
wabt = "0.4"
Expand Down
98 changes: 98 additions & 0 deletions core/src/actor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use agent::keys::Keys;
use error::HolochainError;
use futures::executor::block_on;
use hash_table::{pair::Pair, pair_meta::PairMeta};
use riker::actors::*;
use riker_default::DefaultModel;
use riker_patterns::ask::ask;

#[derive(Clone, Debug)]
/// riker protocol for all our actors
/// currently this is flat but may be nested/namespaced in the future or multi-protocol riker
/// @see https://github.com/riker-rs/riker/issues/17
pub enum Protocol {
/// Chain::set_top_pair()
SetTopPair(Option<Pair>),
SetTopPairResult(Result<Option<Pair>, HolochainError>),

/// Chain::top_pair()
TopPair,
TopPairResult(Option<Pair>),

/// HashTable::setup()
Setup,
SetupResult(Result<(), HolochainError>),

/// HashTable::teardown()
Teardown,
TeardownResult(Result<(), HolochainError>),

/// HashTable::modify()
Modify {
keys: Keys,
old_pair: Pair,
new_pair: Pair,
},
ModifyResult(Result<(), HolochainError>),

/// HashTable::retract()
Retract {
keys: Keys,
pair: Pair,
},
RetractResult(Result<(), HolochainError>),

/// HashTable::assert_meta()
AssertMeta(PairMeta),
AssertMetaResult(Result<(), HolochainError>),

/// HashTable::get_meta()
Meta(String),
MetaResult(Result<Option<PairMeta>, HolochainError>),

/// HashTable::get_pair_meta()
PairMeta(Pair),
PairMetaResult(Result<Vec<PairMeta>, HolochainError>),

/// HashTable::pair()
Pair(String),
PairResult(Result<Option<Pair>, HolochainError>),

/// HashTable::commit()
Commit(Pair),
CommitResult(Result<(), HolochainError>),
}

/// this is the global state that manages every actor
/// to be thread/concurrency safe there must only ever be one actor system
/// @see https://github.com/riker-rs/riker/issues/17
/// @see http://riker.rs/actors/#creating-actors
lazy_static! {
pub static ref SYS: ActorSystem<Protocol> = {
let model: DefaultModel<Protocol> = DefaultModel::new();
ActorSystem::new(&model).unwrap()
};
}

/// required by riker
impl Into<ActorMsg<Protocol>> for Protocol {
fn into(self) -> ActorMsg<Protocol> {
ActorMsg::User(self)
}
}

/// convenience trait to build fake synchronous facades for actors
pub trait AskSelf {
/// adapter for synchronous code to interact with an actor
/// uses the ask() fn from riker patterns under the hood to create a future then block on it
/// handles passing the actor system through to ask() to hide that implementation detail
/// @see http://riker.rs/patterns/#ask
fn block_on_ask(&self, message: Protocol) -> Protocol;
}

impl AskSelf for ActorRef<Protocol> {
fn block_on_ask(&self, message: Protocol) -> Protocol {
let a = ask(&(*SYS), self, message);
block_on(a).unwrap()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make this a Result?

}
}
102 changes: 49 additions & 53 deletions core/src/agent/state.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
use action::{Action, ActionWrapper, AgentReduceFn};
use agent::keys::Keys;
use chain::Chain;
use chain::{Chain, SourceChain};
use context::Context;
use error::HolochainError;
use hash_table::{entry::Entry, memory::MemTable, pair::Pair};
use hash_table::pair::Pair;
use instance::Observer;
use std::{
collections::HashMap,
rc::Rc,
sync::{mpsc::Sender, Arc},
};

#[derive(Clone, Debug, PartialEq, Default)]
#[derive(Clone, Debug, PartialEq)]
/// struct to track the internal state of an agent exposed to reducers/observers
pub struct AgentState {
keys: Option<Keys>,
// @TODO how should this work with chains/HTs?
// @see https://github.com/holochain/holochain-rust/issues/137
// @see https://github.com/holochain/holochain-rust/issues/135
top_pair: Option<Pair>,
/// every action and the result of that action
// @TODO this will blow up memory, implement as some kind of dropping/FIFO with a limit?
// @see https://github.com/holochain/holochain-rust/issues/166
actions: HashMap<ActionWrapper, ActionResponse>,
chain: Chain,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this much more that the state has a chain than a top_pair

}

impl AgentState {
/// builds a new, empty AgentState
pub fn new() -> AgentState {
pub fn new(chain: &Chain) -> AgentState {
AgentState {
keys: None,
top_pair: None,
actions: HashMap::new(),
chain: chain.clone(),
}
}

Expand All @@ -40,10 +36,9 @@ impl AgentState {
self.keys.clone()
}

/// getter for a copy of self.top_pair
/// should be used with a source chain for validation/safety
pub fn top_pair(&self) -> Option<Pair> {
self.top_pair.clone()
/// getter for the chain
pub fn chain(&self) -> &Chain {
&self.chain
}

/// getter for a copy of self.actions
Expand Down Expand Up @@ -98,17 +93,12 @@ fn reduce_commit(
let action = action_wrapper.action();
let entry = unwrap_to!(action => Action::Commit);

// add entry to source chain
// @TODO this does nothing!
// it needs to get something stateless from the agent state that points to
// something stateful that can handle an entire hash table (e.g. actor)
// @see https://github.com/holochain/holochain-rust/issues/135
// @see https://github.com/holochain/holochain-rust/issues/148
let mut chain = Chain::new(Rc::new(MemTable::new()));
// @TODO validation dispatch should go here rather than upstream in invoke_commit
// @see https://github.com/holochain/holochain-rust/issues/256

state.actions.insert(
action_wrapper.clone(),
ActionResponse::Commit(chain.push_entry(&entry)),
ActionResponse::Commit(state.chain.push_entry(&entry)),
);
}

Expand All @@ -124,27 +114,19 @@ fn reduce_get(
let action = action_wrapper.action();
let key = unwrap_to!(action => Action::Get);

// get pair from source chain
// @TODO this does nothing!
// it needs to get something stateless from the agent state that points to
// something stateful that can handle an entire hash table (e.g. actor)
// @see https://github.com/holochain/holochain-rust/issues/135
// @see https://github.com/holochain/holochain-rust/issues/148

// drop in a dummy entry for testing
let mut chain = Chain::new(Rc::new(MemTable::new()));
let e = Entry::new("testEntryType", "test entry content");
chain.push_entry(&e).expect("test entry should be valid");
let result = state.chain.entry(&key.clone());

// @TODO if the get fails local, do a network get
// @see https://github.com/holochain/holochain-rust/issues/167

let result = chain
.entry(&key)
.expect("should be able to get entry that we just added");
state
.actions
.insert(action_wrapper.clone(), ActionResponse::Get(result.clone()));
state.actions.insert(
action_wrapper.clone(),
ActionResponse::Get(
result
.clone()
.expect("should be able to get entry that we just added"),
),
);
}

/// maps incoming action to the correct handler
Expand Down Expand Up @@ -185,14 +167,15 @@ pub fn reduce(
pub mod tests {
use super::{reduce_commit, reduce_get, ActionResponse, AgentState};
use action::tests::{test_action_wrapper_commit, test_action_wrapper_get};
use chain::tests::test_chain;
use error::HolochainError;
use hash_table::pair::tests::test_pair;
use instance::tests::{test_context, test_instance_blank};
use std::collections::HashMap;
use std::{collections::HashMap, sync::Arc};

/// dummy agent state
pub fn test_agent_state() -> AgentState {
AgentState::new()
AgentState::new(&test_chain())
}

/// dummy action response for a successful commit as test_pair()
Expand All @@ -217,12 +200,6 @@ pub mod tests {
assert_eq!(None, test_agent_state().keys());
}

#[test]
/// test for the agent state top pair getter
fn agent_state_top_pair() {
assert_eq!(None, test_agent_state().top_pair());
}

#[test]
/// test for the agent state actions getter
fn agent_state_actions() {
Expand Down Expand Up @@ -255,22 +232,41 @@ pub mod tests {
/// test for reducing get
fn test_reduce_get() {
let mut state = test_agent_state();
let action_wrapper = test_action_wrapper_get();
let context = test_context("foo");

let instance = test_instance_blank();

let aw1 = test_action_wrapper_get();
reduce_get(
test_context("foo"),
Arc::clone(&context),
&mut state,
&action_wrapper,
&aw1,
&instance.action_channel().clone(),
&instance.observer_channel().clone(),
);

assert_eq!(
state.actions().get(&action_wrapper),
Some(&test_action_response_get()),
// nothing has been committed so the get must be None
assert_eq!(state.actions().get(&aw1), Some(&ActionResponse::Get(None)),);

// do a round trip
reduce_commit(
Arc::clone(&context),
&mut state,
&test_action_wrapper_commit(),
&instance.action_channel().clone(),
&instance.observer_channel().clone(),
);

let aw2 = test_action_wrapper_get();
reduce_get(
Arc::clone(&context),
&mut state,
&aw2,
&instance.action_channel().clone(),
&instance.observer_channel().clone(),
);

assert_eq!(state.actions().get(&aw2), Some(&test_action_response_get()),);
}

#[test]
Expand Down
Loading