<dwrensha> geofft: the purpose of the Reader::borrow() functions is to make it easier to write code that works for both Readers and Builders, as I do here: https://github.com/dwrensha/capnpc-rust/blob/master/test/test_util.rs#L125-L230
<dwrensha> (in Rust you need to use a macro to do this, whereas in C++ you'd just use templating)
<dwrensha> interface_list::Reader::borrow should probably exist for consistency. Though it looks like I haven't actually implemented it for all of the other list types, so meh.
<dwrensha> geofft: I think that any nontrivial tests for interface_list would need to go in capnp-rpc-rust
<dwrensha> we should add a /tests directory as we have in capnpc-rust
<dwrensha> hm... though maybe in capnp-rpc there is less of a bootstrapping problem, so that /tests doesn't need to be in its own crate (In capnpc-rust, /tests is its own crate because otherwise how would it handle code generation?)
gopar has joined #sandstorm
jadewang has quit [Remote host closed the connection]
wat has quit [Quit: a]
wat has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Remote host closed the connection]
decipherstatic_ has quit [Remote host closed the connection]
decipherstatic has joined #sandstorm
jadewang has joined #sandstorm
gopar has quit [Quit: Leaving]
dwrensha has quit [Ping timeout: 256 seconds]
mort___ has quit [Quit: Leaving.]
dwrensha has joined #sandstorm
<jadewang> have you seen this draw.io survey? https://plus.google.com/+DrawIo1/posts/hvMEwaCp7NT
dwrensha_ has joined #sandstorm
dwrensha has quit [Ping timeout: 264 seconds]
dwrensha_ is now known as dwrensha
larjona has joined #sandstorm
jadewang has quit [Remote host closed the connection]
mort___ has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 244 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 256 seconds]
NwS has joined #sandstorm
mort___ has quit [Ping timeout: 252 seconds]
mort___ has joined #sandstorm
mort___ has quit [Quit: Leaving.]
Isla_de_Muerte has joined #sandstorm
NwS has quit [Disconnected by services]
Isla_de_Muerte is now known as NwS
mort___ has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 244 seconds]
mort___ has quit [Ping timeout: 246 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 246 seconds]
NOTevil has joined #sandstorm
NOTevil has left #sandstorm [#sandstorm]
XgF has quit [Read error: Connection reset by peer]
XgF has joined #sandstorm
<dwrensha> The latest rustc nightly no longer panics when /proc is not mounted. \o/
NwS has quit [Quit: See you in Isla de Muerte!]
XgF has quit [Ping timeout: 255 seconds]
XgF has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 255 seconds]
larjona_ has joined #sandstorm
wat has quit [Quit: a]
larjona has quit [Quit: Konversation terminated!]
larjona_ is now known as larjona
<paulproteus> dwrensha: Super rad.
<dwrensha> now someone can make the playpen into a sandstorm app: https://play.rust-lang.org/
wat has joined #sandstorm
jadewang has joined #sandstorm
XgF has quit [Ping timeout: 255 seconds]
XgF has joined #sandstorm
jadewang has quit [Ping timeout: 265 seconds]
* paulproteus waves informationlessly
<warren> paulproteus: hi, have a moment?
<paulproteus> In the middle of some things but ping me in an hour?
<warren> sure
<paulproteus> Thanks!
jparyani_letscha has joined #sandstorm
wat has quit [Quit: a]
jadewang has joined #sandstorm
jadewang has quit [Remote host closed the connection]
wat has joined #sandstorm
wat has quit [Client Quit]
jadewang has joined #sandstorm
jadewang has quit [Remote host closed the connection]
<dwrensha> `make test` is awesome
<paulproteus> : D
<paulproteus> $(pgrep --parent $XVFB_PID node)
<paulproteus> It's like CSS selectors for processes.
larjona has quit [Quit: Konversation terminated!]
larjona has joined #sandstorm
<warren> paulproteus: is now a better time?
<paulproteus> Sure.
<geofft> ugh, is the way to convert a struct that impls an interface to a capability ToClient(thing).from_server(None::<LocalClient>)?
<geofft> (in capnproto-rust)
<geofft> does anyone actually use the FromServer trait? I feel like this could just be a straightup function
<dwrensha> geofft: yeah, that ToClient thing is really ugly
<dwrensha> geofft: I'll need to remind myself of the purpose of FromServer...
<geofft> git grepping, it only seems to be used in the examples
<dwrensha> geofft: I'm not remembering any good reason why FromServer needs to be a trait
<dwrensha> geofft: Also, looks like we can do away with the the `hook: Option<T>` argument and make `T` a type parameter
<dwrensha> ... and change the signature of ServerHook::new_client() so that it doesn't take an "unused optional self"
<dwrensha> and then in FromServer::from_server, call `T::new_client()`
<geofft> hm, I'm stuck somewhere more basic. ToClient seems to want to take ownership?
<dwrensha> Right. If you have a Server and want to call it from the RPC system, you have to hand it off to the RPC system.
<dwrensha> ... and you get back a Client that you can call.
<geofft> ok, I feel like I did something wrong in my design then.
<geofft> on the capnp side, I have a bootstrap interface that can give me a List(Workspace), and each Workspace can give me a List(Command)
<geofft> I _thought_ I want to implement this with a struct Bootstrap {workspaces: Vec<Workspace>), struct Workspace {commands: Vec<Command>}
<geofft> and impl bootstrap::Server for Bootstrap, impl workspace::Server for Workspace
<geofft> should I be using something other than an owning vec? like should I hold an owning vec of Clients or something?
<geofft> (or should I be backing this by real capnp structures? at the moment I'm looping over the vec to populate the return of getWorkspaces() and getCommands(), which feels maybe wrong)
<dwrensha> pseudo-capnp schema:
<dwrensha> interface BootStrap { getWorkSpaces() -> List(Workspace); }
<dwrensha> interface Workspace { getCommands() -> List(Command); }
<dwrensha> there are a number of ways you could get that to work. I'm not sure which is best.
<dwrensha> You certainly won't be able to keep owning the WorkspaceImpls after you've returned them.
<dwrensha> You could hold onto something like Vec<Rc<RefCell<WorkspaceImpl>>>, and implement Workspace::Server fo Rc<RefCell<WorkspaceImpl>>
<dwrensha> but that's kind of ugly
<dwrensha> the RPC system does its own refcounting, so it would be sad if you had to do your own refcounting too
<geofft> yeah, thinking a bit more, I think the reason I'm confused is that the calculator example has no nontrivial data (afaict)
<geofft> just numbers and static data like operators
<dwrensha> it's all interfaces!
<dwrensha> objects the whole way down!
<geofft> so if I want a Command that holds something like a std::Process::Child, which can't be directly represented in a capnp message, can't be copied, etc.
<dwrensha> it would be nice if we had another more straightfoward RPC example
<geofft> either I want a struct Command { child: Child } with impl command::Server for Command
<geofft> or a struct Command { child: Child, rpcserver: CommandImpl }
<geofft> and I think ownership in Rust gets super hairy for the second approach
<geofft> 'cause rpcserver wants a reference to child so it can do stuff on child
<dwrensha> hm... it occurs to me that my Rc suggestion doesn't work because the Server needs to be 'static in order to pass it to the RPC system
<geofft> I'd be happy to hand the first type of struct Command off to the RPC system, if I have a way to get it back so I can use the child
<geofft> but it feels like getting a command::Client doesn't really help me?
<dwrensha> ... or, rather, 'static + Send
<maurer> geofft: I could be mistaken, but could you not just wrap a std::Process::Child in a capnproto interface?
<maurer> geofft: And then send the capability pointer to the other thread, which would be sendable, because the child never actually goes anywhere?
<maurer> geofft: Like, if the problem is that you can't ship/serialize std::Process::Child around, it seems like a prime candidate for wrapping in an interface and just talking to over rpc
<geofft> I'm trying to figure out _how_ to wrap it
<maurer> Oh, sorry, guess I misread
* maurer reads up
<geofft> the Child itself stays entirely on the server, the client only interacts with it over capnp-rpc ("write to stdin" / "call this method on this interface when it writes to stdout")
<geofft> I might be misunderstanding you because I am pretty confused right now :)
<maurer> 16:28 < geofft> so if I want a Command that holds something like a std::Process::Child, which can't be directly represented in a capnp message, can't be copied, etc.
<maurer> was the thing I was trying to respond to
<geofft> right. I'm trying to figure out how to define a structure that contains a Child and also can be interacted with over capnproto-rpc
<maurer> a way to represent the Child in your Command message would be to make a parameter to your Command message be a capability corresponding to the child
<geofft> (which feels like it should be an obvious thing, yes, but I'm not seeing an example)
<maurer> OK, now I don't understand what you're trying to do, or where your issues are
<maurer> Do you have code up somewhere?
<maurer> A .capnp file maybe?
<geofft> I can toss code up somewhere if that'd help, sure, but lemme see if I can try explaining better?
<geofft> or ... do you want me to impl something::Server for std::Process::Child _itself_? that might work
<maurer> That is what I was suggesting
<maurer> e.g. your interface would probably (assuming i'm thinking of it right) look something like
<maurer> bootstrap->getWorkspaces() producing a list of workspaces
<dwrensha> geofft: the model right now for capnp-rpc-rust is "each object lives in its own thread". So if your Command::Server needs access to a Child and you need access to that Child elsewhere, you're going to need to synchronize
<maurer> workspace->someCommands(), some of which produce threads
<maurer> thread->theThingYouWerepreviouslyMakingACommand()
<maurer> dwrensha: re: that, is the plan to solve that in the long term by using gj?
<maurer> Since gj will have an explicit event loop to talk about, so putting n objects in a thread will have a direct implementation?
<geofft> "each object lives in its own thread" as in one thread per interface?
<maurer> geofft: Yes.
<maurer> geofft: well, per object implementing an interface, but yeah
<geofft> ohhh, not at most one thread per interface (but lots of interfaces in a single thread)?
<geofft> yeah per object
<geofft> ok that makes more sense now I think.
<maurer> If your implementation of an object wants to spawn a thread that's fine
<maurer> but the way the event system works is that each object has an associated thread that waits on a message queue
<maurer> then dispatches to the right methods
<geofft> so I can't have one object that impls an interface and owns another object that impls an interface.
<maurer> Not which owns it, no
<maurer> Unless there is some deep thread voodoo I'm unaware of available in modern rust
<geofft> struct Foo {things: Vec<Thing>}; impl foo::Server for Foo; struct Thing; impl thing::Server for Thing;
<dwrensha> geofft: let me try to take a step back here
<geofft> like that's the general thing I was trying to make work, and I think I was conceptually confused about that.
<dwrensha> geofft: you want to write an object that implements Command
<dwrensha> and that object wants access to a Child
<geofft> yup
<dwrensha> you also want some other access to that child
<dwrensha> but through a different interface?
<geofft> I _think_ I only need capnp methods on that object to be able to access the child
<paulproteus> A thing I am doing now: Using Vagrant to download a modern.ie image.
<geofft> but... I guess the model that my brain is used to is adding D-Bus bindings to something in Qt or GTK+
<geofft> where you can make a standalone object structure, and drop bindings/exports on top of it
<geofft> and this is sufficiently different.
<geofft> dwrensha: so, I wasn't yet at the point of throwing a Child in the structure
<dwrensha> Now I'm thinking about what "facets" would look like in Cap'n Proto (http://www.erights.org/elib/capability/ode/ode-objects.html)
<geofft> but the calculator example involves creating a new SomethingImpl object at every site that you're returning a capability
<geofft> and I didn't want to do that, I wanted to hand the RPC system a reference to an existing object that I already own
<geofft> because I knew in the future I wouldn't want to create a new CommandImpl object with a new Child, I want to track the existing Child
<geofft> but maybe what I should be doing is creating a new CommandImpl object with a reference to an existing Child?
<geofft> or creating a new CommandImpl object with an RPC reference to an RPC-system-owned Child, which is the thing maurer suggested
<dwrensha> Yeah, making everything a Cap'n Proto object sounds cleanest to me.
<dwrensha> or, at least, it sounds to me like your only hope of avoiding Arc and Mutex/RwLock
<geofft> does this change notably with a GJ-based capnproto-rust? long-term, I don't really want two threads per child process :(
<geofft> short-term, whatever
<dwrensha> Yeah, I think in a GJ would you would have a Rc<RefCell<Child>> that you would share with the CommandImpl
<geofft> if you're curious, https://paste.debian.net/284977/ is the .capnp file that I'm trying to get implemented to convince myself this will work
<geofft> it is way incomplete
<dwrensha> *GJ world*
<paulproteus> Oh hey geofft this is a cool capnp file.
<geofft> yeah I suppose GJ will involve enough changes that I shouldn't optimize for "am I gonna have to rewrite everything"
<geofft> i,i "plan to throw one away"
<dwrensha> In C++ you might just share references to the Child without reference counting. Less overhead, but more dangerous.
<geofft> I keep thinking I should write this in C++ just because the capnp infrastructure is way more mature, and also I don't have to do infinite bindings to signals and subprocesses and termios
<geofft> butbut Rust
<geofft> ok, I have an idea of where to go from here, thanks dwrensha and maurer :)
<dwrensha> geofft: you are providing me with valuable feedback :)
<geofft> once I get somewhere, I'm happy to turn this into an example if you want capnp-rpc-rust to have something with more complicated ownership than the calculator thing
<dwrensha> geofft: that could be cool :)
<paulproteus> Agreed.
<geofft> hm, I suppose I want a separate .capnp file for the server-internal interface to Child?
<geofft> although now I'm second guessing myself about whether any of that is actually internal and how capabilities vs. public/private works.
<paulproteus> I see, modern.ie is 32-bit. Hmm.
<larjona> Hi everybody. I'm having some troubles to understand sandstorm.io. I have deployed my instance in my home server. I have installed gitweb,created two repos, and the URL for cloning is changing each time I click in "home" in the gitweb repo. Whatever. I didn't understand very well gitweb, so I uninstalled the app. But my repos are still there. Shouldn't them be destroyed when I uninstall the app?
<paulproteus> larjona: Installing/uninstalling is mostly about the ability to create _new_ instances of the app (aka new repositories in this case).
<paulproteus> The current design is that uninstalling an app doesn't break your ability to use instances you've already created.
<paulproteus> Maybe that's confusing, and the "Uninstall" process should say something to that effect, like, "App uninstalled. OK to retain existing app instances, or Delete All GitWeb Data?"
<dwrensha> larjona: the "different URL each time" thing is the expected behavior
<dwrensha> larjona: we generate a new token each time, but they go away quickly unless you actually connect with a git client
<larjona> but if somebody git clones with that url, will it be persistent? I mean, if two weeks later she wants to update her clone with git pul
<larjona> pull*
<kentonv> larjona: yes
<kentonv> you can keep pushing and pulling without entering a new URL
<larjona> And the password?
<kentonv> the password will continue to work
<kentonv> the idea is that by handing out different passwords, you could, in theory, separately revoke them. We haven't built the UI for that yet, though.
<larjona> I understand
<kentonv> larjona: ideally you should use the git credentials helper to save the password, so you don't have to type it in repeatedly... we need better instructions for that.
<dwrensha> also, we should show some kind of visual indication for when you successfully connect a git client
<larjona> Thanks.
<maurer> geofft: if you want to see a "real" project using capnp-rpc-rust, you can look at maurer/holmes
<maurer> geofft: Unfortunately I don't quite have approval to release some of the daemons that talk to it yet, but you can get an idea of how I'm using it
<dwrensha> i,i release the demons
<geofft> Krak'n Proto
<dwrensha> paging aldeka ^
<dwrensha> I would wear that T -shirt
<aldeka> soggies may rule
<aldeka> That sounds like a hy capnp implementation.
bb010g has quit [Quit: Connection closed for inactivity]
<geofft> ohhhh now I understand why everything has a +Send bound :(
<geofft> cause it's literally all on different threads
<maurer> Yes.
<maurer> If gj does what I think it's going to do, the send bound might be removable by connecting the object to the event loop in the current thread
<maurer> but I am not the designer, so that's for dwrensha to say
<dwrensha> Yes, in GJ your Servers would not need to be Send
bb010g has joined #sandstorm
<geofft> maurer: this is helpful, thanks!
<geofft> I'm looking at HolmesImpl::new_func 'cause that seems to be the one interesting use of interfaces
<maurer> Yeah, that's intended to allow external programs to register themselves with the logic engine
<maurer> so they can be like "Hey, I implement a function called foo, let users call it in rules"
<maurer> the whole thing is not as capabilities oriented as it could be - right now the API enforces a spoke architecture
<maurer> If I were to do it "right", I'd stop using string names in the code representation of rules and use capabilities directly
<maurer> but I've got other things to work on
<geofft> ... wait up, why is Box<ClientHook+Send> a unique-ownership type?
<dwrensha> geofft: there's a copy() method, I think
<dwrensha> which increases the refcount
<geofft> oh so there is
<paulproteus> I love writing tests in installer-tests/ !
larjona has quit [Quit: Konversation terminated!]
<dwrensha> I see that Jenkins failed again with " expected target->getBrand() == this; 'Disembargo' of type 'senderLoopback' sent to an object that does not point back to the sender. "
<dwrensha> I was just now able to get that to happen again on my machine
<dwrensha> I'll see if I can get anywhere on isolating it...
<paulproteus> I'm honestly pretty happy with how we handled https://github.com/sandstorm-io/sandstorm/issues/616 and the fact that I was able to write a test for https://github.com/sandstorm-io/sandstorm/issues/614
<zarvox> dwrensha: glad it is proving useful! :D
<geofft> er hm. I'm confused again I think. FromServer has a module::Server + Send + 'static bound.
<geofft> so any struct I pass to FromServer, and any data inside it, has to be Send + 'static
<geofft> so I'm not sure how to implement an interface that exposes a struct that includes non-Send data, a non-static reference, etc.
<geofft> like I'm okay with generating that data once the structure is on the right thread, but I don't think I can do that within Rust's type system?
<geofft> I can't say "okay, yo, I'm no longer Send"
<dwrensha> geofft: I suppose that any such data will necessarily only be accessible from the Server object
<dwrensha> perhaps thread-local storage can help?
<dwrensha> though I'm curious to understand better the usage pattern that you want
<dwrensha> geofft: what do you mean that the interface "exposes a struct"?
<geofft> the child thing still -- if std::process::Child is not Send + 'static, then I can't usefully have it implement some_capnp::child::Server
<geofft> and if a struct contains a private std::process::Child member, it won't be Send + 'static either
<geofft> so how do I write a thing that implements some_capnp::child::Server and can use a std::process::Child as if it were a member variable?
<geofft> (doesn't have to directly be a member, but I don't _think_ Rc or anything helps me)
<dwrensha> wait, ::std::process::Child is not Send+'static? that's surprising to me
<dwrensha> it doesn't appear to be parameterized by any lifetimes