Skip to content

Commit 9dd187e

Browse files
lutterJannis Pohlmann
authored andcommitted
runtime/wasm (ipfs_map): add ability to pass extra userData through
This changes the signature of ipfs.map to `ipfs.map(hash, callback, userData, flags)`, with the corresponding change to the callback's signature as `callback(jsonData, userData)`
1 parent 175ebce commit 9dd187e

File tree

5 files changed

+42
-24
lines changed

5 files changed

+42
-24
lines changed

runtime/wasm/src/host_exports.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use ethabi::Token;
44
use futures::sync::oneshot;
55
use graph::components::ethereum::*;
66
use graph::components::store::EntityKey;
7+
use graph::data::store;
78
use graph::prelude::*;
89
use graph::serde_json;
910
use graph::web3::types::H160;
@@ -347,12 +348,15 @@ where
347348
// return value contains all entity operations that were produced by the
348349
// callback invocations. Each invocation of `callback` happens in its own
349350
// instance of a WASM module, which is identical to `module` when it was
350-
// first started.
351+
// first started. The signature of the callback must be
352+
// `callback(JSONValue, Value)`, and the `userData` parameter is passed
353+
// to the callback without any changes
351354
pub(crate) fn ipfs_map(
352355
&self,
353356
module: &WasmiModule<E, L, S, U>,
354357
link: String,
355358
callback: &str,
359+
user_data: store::Value,
356360
flags: Vec<String>,
357361
) -> Result<Vec<EntityOperation>, HostExportError<impl ExportError>> {
358362
const JSON_FLAG: &str = "json";
@@ -382,7 +386,8 @@ where
382386
valid_module.clone(),
383387
ctx.clone(),
384388
)?;
385-
let result = module.handle_json_callback(&*callback, &sv.value);
389+
let result =
390+
module.handle_json_callback(&*callback, &sv.value, &user_data);
386391
// Log progress every 15s
387392
if last_log.elapsed() > Duration::from_secs(15) {
388393
debug!(

runtime/wasm/src/module/mod.rs

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use wasmi::{
1212
use crate::host_exports::{self, HostExportError, HostExports};
1313
use crate::EventHandlerContext;
1414
use graph::components::ethereum::*;
15+
use graph::data::store;
1516
use graph::data::subgraph::DataSource;
1617
use graph::ethabi::LogParam;
1718
use graph::prelude::{Error as FailureError, *};
@@ -276,14 +277,16 @@ where
276277
mut self,
277278
handler_name: &str,
278279
value: &graph::serde_json::Value,
280+
user_data: &store::Value,
279281
) -> Result<Vec<EntityOperation>, FailureError> {
280282
let value = RuntimeValue::from(self.asc_new(value));
283+
let user_data = RuntimeValue::from(self.asc_new(user_data));
281284

282285
// Invoke the callback
283-
let result = self
284-
.module
285-
.clone()
286-
.invoke_export(handler_name, &[value], &mut self);
286+
let result =
287+
self.module
288+
.clone()
289+
.invoke_export(handler_name, &[value, user_data], &mut self);
287290

288291
// Return either the collected entity operations or an error
289292
result.map(|_| self.ctx.entity_operations).map_err(|e| {
@@ -540,27 +543,31 @@ where
540543
&mut self,
541544
link_ptr: AscPtr<AscString>,
542545
callback: AscPtr<AscString>,
546+
user_data: AscPtr<AscEnum<StoreValueKind>>,
543547
flags: AscPtr<Array<AscPtr<AscString>>>,
544548
) -> Result<Option<RuntimeValue>, Trap> {
545549
let link: String = self.asc_get(link_ptr);
546550
let callback: String = self.asc_get(callback);
551+
let user_data: store::Value = self.asc_get(user_data);
552+
547553
let flags = self.asc_get(flags);
548554
let start_time = Instant::now();
549-
let result = match self
550-
.host_exports()
551-
.ipfs_map(&self, link.clone(), &*callback, flags)
552-
{
553-
Ok(ops) => {
554-
debug!(self.logger, "Successfully processed file with ipfs.map";
555+
let result =
556+
match self
557+
.host_exports()
558+
.ipfs_map(&self, link.clone(), &*callback, user_data, flags)
559+
{
560+
Ok(ops) => {
561+
debug!(self.logger, "Successfully processed file with ipfs.map";
555562
"link" => &link,
556563
"callback" => &*callback,
557564
"entity_operations" => ops.len(),
558565
"time" => start_time.elapsed().as_millis());
559-
self.ctx.entity_operations.extend(ops);
560-
Ok(None)
561-
}
562-
Err(e) => Err(e.into()),
563-
};
566+
self.ctx.entity_operations.extend(ops);
567+
Ok(None)
568+
}
569+
Err(e) => Err(e.into()),
570+
};
564571

565572
// Advance this module's start time by the time it took to run the entire
566573
// ipfs_map. This has the effect of not charging this module for the time
@@ -859,6 +866,7 @@ where
859866
args.nth_checked(0)?,
860867
args.nth_checked(1)?,
861868
args.nth_checked(2)?,
869+
args.nth_checked(3)?,
862870
),
863871
_ => panic!("Unimplemented function at {}", index),
864872
}

runtime/wasm/src/module/test.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,18 +294,22 @@ fn ipfs_cat() {
294294
assert_eq!(data, "42");
295295
}
296296

297+
// The user_data value we use with calls to ipfs_map
298+
const USER_DATA: &str = "user_data";
299+
297300
fn make_thing(id: &str, value: &str) -> (String, EntityOperation) {
298301
let mut data = Entity::new();
299302
data.set("id", id);
300303
data.set("value", value);
304+
data.set("extra", USER_DATA);
301305
let subgraph_id = SubgraphDeploymentId::new("wasmModuleTest").unwrap();
302306
let key = EntityKey {
303307
subgraph_id,
304308
entity_type: "Thing".to_string(),
305309
entity_id: id.to_string(),
306310
};
307311
(
308-
format!("{{ \"id\": \"{}\", \"value\": \"{}\" }}", id, value),
312+
format!("{{ \"id\": \"{}\", \"value\": \"{}\"}}", id, value),
309313
EntityOperation::Set { key, data },
310314
)
311315
}
@@ -329,10 +333,10 @@ fn ipfs_map() {
329333
.unwrap()
330334
.hash
331335
};
332-
336+
let user_data = RuntimeValue::from(module.asc_new(USER_DATA));
333337
let converted = module.module.clone().invoke_export(
334338
"ipfsMap",
335-
&[RuntimeValue::from(module.asc_new(&hash))],
339+
&[RuntimeValue::from(module.asc_new(&hash)), user_data],
336340
&mut module,
337341
)?;
338342
assert_eq!(None, converted);

runtime/wasm/wasm_test/ipfs_map.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,10 @@ class JSONValue {
121121
* Actual setup for the test
122122
*/
123123
declare namespace ipfs {
124-
function map(hash: String, callback: String, flags: String[]): void
124+
function map(hash: String, callback: String, userData: Value, flags: String[]): void
125125
}
126126

127-
export function echoToStore(data: JSONValue): void {
127+
export function echoToStore(data: JSONValue, userData: Value): void {
128128
// expect a map of the form { "id": "anId", "value": "aValue" }
129129
let map = data.toObject();
130130
let id = map.get("id").toString();
@@ -133,9 +133,10 @@ export function echoToStore(data: JSONValue): void {
133133
let entity = new Entity();
134134
entity.set("id", Value.fromString(id));
135135
entity.set("value", Value.fromString(value));
136+
entity.set("extra", userData);
136137
store.set("Thing", id, entity);
137138
}
138139

139-
export function ipfsMap(hash: string): void {
140-
ipfs.map(hash, "echoToStore", ["json"])
140+
export function ipfsMap(hash: string, userData: string): void {
141+
ipfs.map(hash, "echoToStore", Value.fromString(userData), ["json"])
141142
}

runtime/wasm/wasm_test/ipfs_map.wasm

38 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)