 Cool. You guys look sleepy. You guys having fun? No coffee? Oh, fail. We need some Red Bull up in here. Would it help if I started dancing and shouting, developers, developers, developers, developers? Would that help? Okay. Cool. Alright, so this is a Pureware desktop application development with Ruby Threads and Juneta. I'm actually really happy that there's been a lot of talks today about distributed computing, about threading, about I.O., because those are all really important topics, specifically because, you know, Ruby gets a lot of flack, I think, for not being very performant, and there's a lot of good reasons for that. And so this talk does touch briefly on some of those, not to dwell on them and not to dwell on some of the other products or packages and gems I've already been released, but really to talk about the paradigm of pureware desktop application development. In some cases, server-aware, or pureware server-side development as well. This stuff really isn't specific to desktop applications. And also the way OpenRain, like one of the tools that we released, called Juneta, which is kind of in the area of pure awareness and communication, which makes it pretty easy to develop those types of applications. And so let's get the business out of the way. I'm with OpenRain Elite Web Software in Phoenix. These slides are as well as Mark Chung's slides, who's going to be talking tomorrow on Ruby to Ruby, which is really awesome. We'll be available on the OpenRain blog sometime really soon. We are hiring in Phoenix, so if you're in Phoenix, you don't necessarily have to be a Ruby developer, but if you're a bright person and want to work with other bright Ruby developers, come see me. And so there's really, this thing's broken up into three distinct parts. The first one is that why should we really care about point-to-point or peer-to-peer applications, whatever, within Ruby? And I was just talking to James a couple minutes ago, and kind of making an observation that client-side development doesn't seem to be a major focal point of Ruby development. And I think that's unfortunate, because we all use desktops, we interact with GUIs, we do all these wonderful things with GUI apps not written in Ruby, and seeing a lot of Apple computers, obviously a very high percentage of Ruby users or Ruby developers are using Mac computers, I find it kind of odd that we haven't spent a lot of time focusing on GUI frameworks, especially since Apple now supports, or as of today at least, Ruby Cocoa, and has some integration at least with Xcode. And so if you're kind of kosher with using Xcode, or at least using the objective C objects, which provide Ruby Cocoa bindings, you can create rich client applications with Ruby, using the Ruby version which comes bundled with OSX. And so we have just like a really brief proof of concept demo just to show later on, which I'm not going to get into a lot of detail on how it's actually done, because it does get into objective C, because there is some integration with that. But it is possible, we have all of the tools, it's just no one's really focusing on doing it. And so when we talk about P2P, in my opinion, it's really on pigeonholes into a couple of primary applications. I was doing my undergrad in the late 90s, and at that time, if you remember Napster and how popular it was, especially in college campuses, primarily for downloading music. And so to me, when I think of peer-to-peer networks, I'm primarily thinking of applications to download illegal things off of the internet. And all of the variants which surfaced after that, the Nutella's, Kizah's, stuff like that, as well as Bonjour in iChat. Bonjour is a pretty, I think, recognized name in being able to do peer discovery on a local area network. And instant messaging is just one of those examples. But really that's such a small subset of possibilities that we can do with peer-aware applications. I mean, and if we were just to sit down, have a couple beers, and just explore this concept in more detail, we can come up with a huge list of things that we could do and we should be doing, but we're not doing. And just to kind of go down some of the bigger bullet points, pair programming and team debugging. Quick show of hands, who here came to Ruby from either Java or .NET? See, now, rhetorical question, like how do you feel about the development tools which are available in Ruby compared to that in Java or .NET? And if you're like me, I am still somewhat frustrated because we have, you know, Eclipse and the Ruby development toolkit or whatever already he stands for. NetBeans has some support for Ruby, but I don't feel like Ruby is a first-class language in terms of the tools that are available to work with it. And everything from web services or .NET, I mean, you can bust out a web service really quick. I mean, just to be honest with you, it's not in soap. Rest is obviously a different story. But there are some really key use cases. For example, with Eclipse, being able to do team debug, or not team debug, but at least remote debugging of threads running on your machine across the network, which is really useful because if you work in a development shop like I do, at numerous times during the day, I'm saying, hey, could you come look at this? Because I'm missing something obvious. Something's broken. Could you just physically walk over here and share my keyboard and pull up a chair and breathe on my neck and all that stuff while we try to figure out this problem? And, you know, so I think it's pretty easy to envision some sort of, some better tool support where we can actually work together on Ruby projects without having to actually physically share keyboards. But that breaks our common, the paradigm of document models that we're all accustomed to working with. For example, Microsoft Word, I think it's pretty absurd that in 2007, Microsoft Word for OSX is still like a single document which I had an MI keyboard on my machine and I emailed to you guys and then you can email it and you can email it back to me. That's pretty ridiculous. Collaboration. File sharing, you know, completely decentralized file sharing, configuration sharing, grid computing. Again, which is Mark is going to talk about MapReduce, you know, just kind of setting up arbitrary MapReduce servers on a given network to be able to take an ad hoc network like this room right now where the majority of us have machines open or we're all doing something on the Internet. And there's a lot of compute power that's there. But for the scope of this 45-minute conversation, I'm not going to set up a server. I'm not going to spend three hours setting up a server just so we can use some core services in this room. So there has to be some enabling technology that allows us to take advantage of, oh, I don't know, revision control systems like GitJura is a good example for us all to be able to sit here and start collaborating without worrying about all this infrastructure. And so all of these ideas aren't new. They've been around for quite some time. And in Java, and so that came from the Java space, Juxta JXTA is one of those projects which tries to support this type of collaborative communication between Java processes. But in my opinion, it falls short. Because in the typical sun Java way, there's huge implementation specs up the wazoo. There's committees to discuss whether or not changes should get in. And for the size of the project, I mean, that's kind of absurd. Not very well documented, which I do find kind of strange. And it's also inherently intestable. And so I think it's a really noble effort that Juxta is out there and it's still supported. But if I can't test a piece of software scientifically, I can't, sorry, it's working right. I'm not going to be able to know if it's ready for release. And so it juxta to me, and there's books written about Juxta so you can buy them off Amazon used now for like 10 bucks. So if you're interested in kind of like the history of the people trying to develop your applications, especially for the desktop, you kind of have to look at this case. And I have kind of a rant on why I feel it's inherently intestable on my blog, which you're free to flame me about at your discretion. And so enter Juneta. And so, like I mentioned, Juneta is a gem that was really just a couple months ago written in pure Ruby, which allows arbitrary Ruby processes on the same land to talk to each other, providing two primary services of peer discovery and object passing between Ruby processes. And that's very simple, I guess in essence, but at the same time, it supports a lot of those cases we had before, because if we're both using an IDE or some other application on our individual desktops, they need some mechanism to talk to each other. And as has already been discussed today, I think to a great extent, there are IO problems in Ruby with regard to performance. Threading is a big issue, and we'll touch about some of those individually and how you should address those if you're planning and writing a desktop application which needs to talk to other desktop applications. And so there are a couple of primary goals of the gem which make it somewhat distinct, I think, in the space. There are other options available to you. And last year, you know, there were test and then there came out AppJourer, lots of Jourer-based things which are primarily based on DNS-SD. And DNS-SD is a natively compiled implementation of ZeroConf, which is Apple's you know, the BunJourer run debut implementation, whatever. And that's all in good, but at the same time, you know, there are some drawbacks to using native things also, because we kind of lose some of the design power and flexibility of using pure Ruby, and we also have portability issues too, at least in theory. And so portability is a big thing. Having few or little dependencies, if you caught James Bloch's presentation just a couple hours ago, he talks a lot about inversion of control and how, you know, it's kind of unnecessary to use needle and copelands in a lot of cases. And I really identify that because coming from the Java space, you know, I tried to use needle and copelands at the time and found it pretty much unnecessary, but yet in this particular case with Juneta, it's actually, I think, a good example of an application, which does use this inversion of control without needing any sort of inversion of control container, and we'll go to that. Enable collaboration, low learning curve. It took me a long time to get a basic hello world example running on juxtap. And one of the demos I'll show you today is an instant messenger client, which in about 60 lines is a complete group chat, where everybody here can just, you know, fire up and start talking instantly. There are some caveats to that, but that's pretty powerful. And you know, when you can do powerful, so few lines, you kind of just have to wonder, you know, maybe there is something right going on. And no dependencies to be honest. There is a dependency in HO right now, which in theory shouldn't be necessary, but aside from that, it doesn't use event machine. It doesn't really have any reason to kind of anything else. So if you have fast thread available, it will use it and it will help performance a bit. So technical overview of what actually happens within Junetta. It provides asynchronous peer discovery. Some of the networking concepts, you know, we could talk for a long time about those, but we won't get into too much detail. UDP via subnet broadcast. I don't know if that makes any sense to anybody. Basically, there's only a couple ways to find all of you guys on the network. And the two primers, one is a centralized server, but that's not one of the design goals of Junetta. We're supposed to be able to find each other without doing anything else. Without any servers. So that's not really not an option. The other is UDP broadcast, where I can just send a packet out to the Wi-Fi network. And each of you guys, if you're listening on a special address in UDP port, you're going to get that broadcast packet and know that I'm available and be able to respond to me directly with your data. Async and just peer IO. Those are things that kind of get interesting, because Junetta allows you to receive data from peers and send data for peers without actually writing any IO code, which is good and bad, because, you know, you could probably do things with a lot of memory. You can get things backlogged in an outbound message queue, which, you know, you might not know about if your peer doesn't receive them. If all of you guys simultaneously close your laptops and I'm in the middle of sending a big text file to you, I can't guarantee that you're going to get that. You can't guarantee that you're going to receive that, because I can't control what you guys are doing in your machines. Lots of threads. Because of the nature of this constant IO going on, for example, if everybody in this room were in the same chat room, which is completely centralized and we're all sending each other messages, that's a lot of IO going back and forth. And so if I have 100 people sending me data and I have to read all of that concurrently, in the Junetta model, at least, it's going to have 100 threads going on. And for performance reasons, and in Ruby 1.8, that's not going to work for very large scale cases. And so in other run times outside of the MRI, that should improve dramatically. But as an example, you know, if there are people here, and the Ruby thread schedule, I think it's like a 10 millisecond slice, which is allocated. And so with 100 people, in theory, if I have that 100 threads going on, it could take a second before my thread connecting directly to you gets CPU time to be able to receive that data. And that's really unacceptable. The current requirements, if you install the Junetta gem, it'll run OSX or Linux on the 1.8 MRI run time. I really, really, really, really want to get JRuby running, but I'm having some issues with Socket. And so if you can help me with that, I'll give you a t-shirt or a beer or something like that, I really love a patch. Because I'd love to get it running on JRuby. There's just maybe like four lines in the entire gem which need to be changed. And so I love you forever, BFF. Inside the Magic, we talked a little about this, most of the Magic is the networking and multi-threading, and that the engine itself is a facade which allows you to talk to your peers and integrate with your peers without having to really know what's going on under the covers. And so I think that's really powerful. The networking Magic itself, just to cover a few terms, IP address, whatever your distinct note is on the network, one kind of unique property about Junetta is that you can run multiple peers logically on the same machine. And so you'll need to use a different port number, but if for some reason, like testing, for example, you want to launch five instances of the same application on your machine, maybe they're going to be mocked out to some extent, but you can test it actually on your local box. Port number, the way I describe it to my parents is a mailbox at an apartment complex. Just to find what unit in that computer that that should go to. UDP is how peer discovery works in Junetta. Bonjour is the same way, actually. And because UDP can be used to broadcast that across networks. TCP, Transition control protocol. If I want to send data to a specific person that I find, it's going to use a direct TCP connection because I don't need to broadcast that out to everybody. So I'm going to make a direct connection to a TCP and send it directly to them. A subnet Junetta, unlike Juxta and unlike some other libraries available, it does not attempt to work across the internet. It is a local area network only technology. And that was very intentional because the conniptions you have to go through to get this type of thing across the internet are very complex. And so it's just the opinion of the gem that let's not do that if you need to do that use something else. Because you start to get into issues like natural reversal, which is a whole other topic. Getting through proxies and other sorts of corporate firewalls, things like that, which is just kind of a nightmare. And the whole gem is less than like 40k. So it's just not something it handles. And so if you're kind of wondering what type of network this is going to work on, really ADP broadcasts get blocked, tend to get blocked at borders. So whatever the router, you know, if you're in a small home office network, those packets that discover other peers aren't going to go out to the internet. And vice versa, peers on other people's networks aren't going to get to you if you're on just a local area network. The whole concept of using Junetta revolves around peers and peer handlers where it's just an event engine kind of. And if you kind of feel like an event machine where you're like getting events out, managing state event, once you start the engine within your application, you're going to get starting events out. A peer came online, a peer sent you this data, a peer just unregistered, a peer, you know, updated the metadata information. Everything's based off events. And so if you already have a GUI application, GUI applications tend to be event based, right? Because you click on a button and there's some handler or listener which gets fired to handle that. That logic is yours and so all you really have to do is define what happens when that event occurs and it will automatically call that logic. So it's pretty, and we'll have examples of that, so it's pretty easy to use. The throwing issues are a bit troubling and with green threads and Ruby 1.8 there are some benefits to it. One thing that people don't talk about very much is that the consistency across platforms is actually really nice. And if you remember Java back in the 90s, we went through this same thing it seems like where it actually when they first switched to native threading and allowed the kernel to do scheduling across different threads in the same process we had variations across different operating systems and so what would happen is that as a developer I'd be working on Linux under Jboss or Tomcat or whatever was popular at the time and then we'd go into production on a Solaris machine which has a completely different kernel and there'd be problems with threading or something, there's a mutex that was deadlocking somewhere and we'd look at this locally and say I can't reproduce this what's going on. The reason is because with native threads or excuse me, with green threads they're just consistent across all platforms and we don't really have that benefit with native threads but the pros or rather the cons of green threads I think far outweigh this and that's the way the Ruby community is heading in general so I don't think we should fight it. Ruby specific calls like thread that kill for example you won't see that in post-POSIX thread implementations and that's a good thing single CPUs, just kind of quick survey also of your primary development machine whose machines have only one CPU? Nobody. And just to kind of prove this hypothesis, how many people have two or more CPUs on their primary development machine? Yeah. So green threads bad because in green threads we can only use one of those CPUs at a given time and this is an example, some of our web applications are just so pro test first development that those tests could take 30 minutes an hour possibly more on a slower machine and part of this is because they can't execute across two CPUs and so this is a big problem, we've got to fix this and of course a lot of people are working on it. Alright so let's actually get to some code or actually, sorry about some of these other points green threads are probably going to be slower and so performance wise using this Juneta engine that I want to send you a gigabyte of data that's not going to fly for a couple of reasons also because of loading data into memory before sending it out across the network and so there are some cases which aren't really going to work too well and also debugging and testing and this goes back to the tool support issue that we have in .NET and Java but don't flame me or do flame me, I don't know I still feel like we don't have very good tools to debug multi-threaded applications especially with testing multi-threaded applications because I don't know how to use RSpec to test something which has asynchronous components running inside of it I just don't, I mean I guess I can start mocking stuff out, I can try to instrument the thread scheduler I really don't know how to test this stuff so that's kind of a fundamental issue alright so actual code let's actually develop something we actually want to add pure awareness to your application this is pretty much the first thing you'll do is create an engine and if you want to get all technical about it this is follower type 3 inversion of control which is just a fancy way of saying you pass in the logic that you want to execute from these different device types when you create the engine so it's all at construction time there's no complicated XML or YAML or anything like that and they're all optional also so you can create an engine which just sits there turning and doesn't do anything although you probably wouldn't want to do that so you just provide either prox or objects which implement a call method which is basically the same thing and then there's four different types of events in this particular slide the pure handler is what gets executed when somebody sends you data and so my handler assuming that implements on this next slide the call method message going back here you can see this is very simple as soon as it gets a message it's basically just going to print it's a, and it's a basic message object of that type it's going to print some text field with inside of it to the console so that actual logic is very simple and of course this is many more lines it actually needs to be we could do this in one line if we wanted and just specify a prop without defining the my handler type but if you want to be explicit this is how you could go about doing it and then below the engine itself pure port if you want to run multiple instances on your same machine you'll probably now once you use the random port you'll probably want to actually pick one and stick to it when you actually deploy applications groups is a kind of a cool mechanism because it allows all of our genetic based applications on the same network to talk to each other but have some way of distinguishing what each application is capable of doing and so in my examples I think it's my group is called I am example and I have a Rails based example which discovers other Rails apps on the same network I'm kind of like AppJourer which is a similar gem and that has a different group stop on shutdown threading is also one of those things where when you exit an application you need to make sure you're shutting down cleanly especially because IELC could be going on and even though the user of my local machine clicked close that it's only polite to tell anybody else that I'm talking to across the network that I'm going down of course you can't enforce that because we're all I mean if you close your laptop and play it again and you're going down whether I like it or not but stop on shutdown is just like a little helper method which makes sure that threads get shut down fairly cleanly in the end because of the threading which happens internally to Hanzel IO you just call engine.start lastline.j.start and as soon as you call that other peers on the network are going to be seeing you and we'll see that in a few minutes here if you don't want to be seen you can repeat the engine around a memory you can call stop, you can start it again you can restart it and do whatever you want with it and as I mentioned before you can also create multiple engines in memory so defining event handlers yeah these are the two ways that I mentioned you can either create a proc and the peer appears actually in a type which is documented in the general documentation class my handler, depth call, peer connection it's two syn names for saying the exact same thing just do whichever way it's going to send to you here's some explicit information on the different types as I mentioned, peer handler is what you have to provide, the logic you have to provide when somebody actually sends you depth a registered handler is what happens when I discover you on the network for the first time and so under most cases maybe that's only going to happen when you first open your laptop and you start your application and then you might work for 10 minutes then decide you want to leave you'll jump off the network and then your hands will get called because my local machine will notice that you went offline and then peer updated handler every four seconds by default each engine instance will send metadata update to everybody else on the network there are kind of cool hacky things you can do with that under the covers if you want to be clever but really it's just a mechanism to know that this person is indeed still there and I shouldn't make any assumptions about them going offline or anything like that because they're still on the network and so we have this instant messenger application that's actually right, complete this code because we've kind of talked about hands lane peer events but we haven't talked about how we actually send stuff to other peers on the network or really how to even know who's on the network to start with so sending is much much easier because we've already created our engine it's already on the network everybody knows we're there we've started to figure out our engine has started to collect say oh you're online I noticed you, I noticed you, I noticed you and that generally happens within four seconds so we've created this basic message object which has a name and a text and then called the Junetta dot send to known peers and by default every peer on the local network which is in my groups will get this object now so that's pretty cool because like one line just send it to everybody that is going to care about me on the network and all of a sudden they're going to get the object the way that the actual marshaling works it actually just serializes it to YAML and so anything that can be serialized to YAML and on-martial back into an object state via YAML can be sent by Junetta just automatically out of the box in the future there's going to be different ways of registering serialization mechanisms so if you want to send XML eventually you'll be able to send XML but right now it's all YAML based and the other nice thing about that is it also means that in theory you know if you wanted to write another thing on the network which is not written in Ruby you'd be able to handle that as well because YAML is very generic there are things to handle and send and generate YAML in every language and so that shouldn't be a problem in this middle area of code who are my peers, self.knownpeers if you have an area let's say you had a gooey part of your view which just shows everybody that's online kind of like what iCat in Manjure does it shows you know Preston Lee little green dot and then you double click that dot and start typing which allows you to get information on who is known on the network at a given point in time if you iterate through that it will be keyed by a UUID which is almost certainly unique across the network it's actually universally unique as well as a peer connection object which allows you to get their IP address if for some reason you need to know their IP address explicitly you can get it from there if you want another port number from there if you want to add other metadata maybe that gets sent to peers you can have that object and add additional data to it alright so let's actually do some demos so this is actually kind of dangerous for a couple reasons one is that live demos those things that you should never do and i'm going to do it and the other thing is because of security and that genetics is currently a tool there are some very fundamental computer science problems like authorization of peers who you don't know and there's things like Diffie Helman which allow us to exchange keys without necessarily having any sort of predefined data between us but that doesn't necessarily solve this issue of authorization so if i have an application for example which does distributed testing or distributed computing i might want everybody on this side of the room to be able to run their tests on my machine but not people on this side of the room because people on this side of the room are evil and that's just kind of something that needs to be thought out a little bit more and honestly a lot of that is going to be very application specific because it could be the case that maybe you just want to make a a queue on a server you know it does nothing it queues jobs and then there's other things on a network which consumes those jobs and that's it there probably isn't too much of a security risk i mean maybe you're going to churn your Ruby process on your machine or take other security measures but you know it's going to be very application specific on how you deal with those things things we can't demo right now are jRuby again help i need a patch for that as well as Ruby 1.9 because Ruby 1.9 uses native threads and there are some things you know back to the portability of things that threaded applications which are running currently on 1.8 while those applications are going to have problems because there are calls that just aren't going to make sense when we take green threads and make them native so i don't think that's necessarily going to be trivial for some Ruby and server implementations but in this particular case i don't think it should be too hard so let's get out of here mirror display cool so a couple things first thing i'm going to do and i have about 8 or so terminals open here i'm going to watch and all these examples come to the jump if you're at home or something you want to play with it you'll have all the same code with you i'm currently using janetta 0.1.6 which is the current release of it so we're going to watch this network status example and what this is going to do and i'm on my own little private network so just for sage purposes and i'm seeing all the other peers on my network which in this case is just me but i'm running a whole bunch of different applications in this groups column over here that is too dark you see i am example so i'm running an instant messenger client as well as a rails application which is broadcasting its presence to everything across the network and so we're just going to leave this open here as we're doing these demos to see what's going on now i'm going to watch an instant messenger client that's a shortcut for that is it command plus? oh they're real and i'm going to watch a bunch of these this instant messenger is 59 lines of code here's the actual code just to prove and it's going to allow me to talk to other people in kind of like an ad hoc chat room so one with now kind of like IRC but without any IRCs are available where when i'm bringing these peers online or these instant messenger clients online they're automatically finding each other or figuring out how to talk which is pretty cool here's the network status okay so coming online this will be Alice okay i'll start it up and i'm charlie over here i'm going to start up a third one but i'm going to start in debug mode we're going to see a ton of just general presence messages it's kind of interesting because you can kind of i don't know if you can read that it's kind of small but we can see a lot of things a lot of events that are being detected by this peer on the network and so over here for example this is bob and bob will say hi hi Alice she saw that text pretty much instantaneously so these are distinct Ruby processes again there's no server going on they just found each other somehow on my local network and are talking to each other back here in this debug mode for this third instant messenger client we see registering peer peer updated events lots of kind of the numbers are UUIDs of different peers across the network and so we're seeing these broadcast messages actually going around and they're not really being handled they're actually being done with them but the engine itself is detecting them and there's threading obviously going on in the background so even though if we were to type a message here and send it to other peers there's a message on another peer there's still stuff going on in the background with the Ruby threading and this works in this case because there's about three peers there are those caveats of very large numbers of threads and the Ruby thread schedule are kind of being a performance bottleneck there but this is still pretty powerful so the other instant messenger that's an example of pure point-to-point applications or peer-to-peer applications which don't need a centralized server unlike BitTorrent for example which does need some sort of tracker to find peers in most cases but now let's do another example which does require a centralized server and it's actually that queue example that I mentioned so what I'm going to do is fire up another example which comes with a gem called queue server and so this is by itself not if you look at the code it doesn't actually do anything but it's a queue just a thread safe FIFO queue on the network which is going to be available and broadcast itself to everybody else that wants to potentially use it and so if you had I don't know maybe you're writing an application to render frames for Shrek 7 or something and you wanted to delegate rendering every frame to a different machine you might fire up something like queue server like I came up with I said this process is going to be a server it's not something the engine enforces upon you but it's just a concept they added on top of it so I fired up my queue server and it's not doing anything, no one else is using it so let's start using it and queue client and just to make it more interesting I'm going to fire up a second client so we have two clients and there's stuff going on here and then we have a server and so the clients are really having two jobs and they produce work to do they look for a server on the network and once they find it, they throw this work at it so it gets enqueued and so this server is kind of managing all of the work that's being produced on the network and then once the server detects that it has work to do it finds any client which is available to do it and says hey, you need to execute this do this work, whatever it is go off and do it and so on the server side we see that there's jobs getting found and it's delegating that back off to the server so we don't really have any CPU crunch time going on on this queue server process because all of the actual work is being delegated to the clients and on the client side, since the clients have those two jobs like I mentioned, they create jobs and they consume jobs so creating job, in this case 606 and then in this case, the server set the job right back to the client to say you need to actually process this job but then we see below this we're getting created but aren't getting processed by this peer and so if we look at another peer we see that this guy is actually processing it's consuming more jobs than it's producing and so even though this is a fairly trivial example we've created our own distributed work system to crunch different data using different processes without very much integration work at all and so when we're talking about building bigger applications I think this is the type I think this is the right direction that desktop apps should be going with I think our desktop applications especially should be able to talk to each other a lot it's one of those kind of few benefits that we're having it seems like these days to doing a desktop application as opposed to a web application because we can have all of this rich access to the file system and compute power that might be a little harder to leverage on the web and lastly we have a well not last we've got two more demos and I've only got a couple minutes left I think so I'll try to make it fast we have a Rails app so I'm just going to restart real quick this is a just completely bare bones Rails app there's absolutely nothing going on except it uses Juneta under the covers to detect other things that are going on the network and there we go and so it's already picked up something on the network it's going to refresh every second and hopefully it'll pick up more peers I'm short on time so I'm going to jump back to the presentation in terms of GUI apps also Mark actually busted out a really quick Cocoa or Ruby Cocoa application to as a proof of concept this is a paradigm that is worth pursuing and we see text appearing at the console again I'm short on time so I'm just going to jump out of this but these are completely separate processes using Cocoa natively via Objective C and Ruby on OSX using the version of Ruby which ships with OSX Lover so the entire application the Ruby dependency of Juneta and everything is bundled into an app application bundle just like every other OSX application is doing except it's using Ruby under the covers that's pretty cool let's hop back to the slides we've seen the same thing so is it production ready? would I ship an application with this? why not do that? I think it will be but it just isn't right now there are a couple of things it needs to have one is the current version does have a small memory leak which yeah it's kind of bad so I wouldn't use it in production probably for that reason alone but also because of the thread scaling issues in the MRI currently I wouldn't use it until JRuby is working potentially after maybe Rubinius one of these native thread interpreters is much more popular also authentication authorization it doesn't support that out of the box if you want to add it, if you want to encrypt data to another peer sure, go for that it's just not provided by the gem itself because the gem isn't opinionated on how you should talk to other peers so in the future I'll address that and so I guess my summary challenge if you take something away from this presentation my challenge to the people here who are developing these risk client GUI applications is that we need a tool and that tool to me is a supported collaborative IDE for Ruby written in Ruby the IDE part itself in Ruby for Ruby has been attempted before and there are some kind of small open source projects which address that and I think that is absolutely the right direction but also I think there's so many advantages to DSLs, metaprogramming in Ruby that don't really work so hot in Java and .NET we should have a tool which reflects how awesome Ruby is and I think especially in the enterprise having that type of tool available will go a long way to Ruby adoption to really help fuel growth here's a few examples which I kind of draw inspiration from the one on the left is called OpenCoke it's kind of hard to describe succinctly but it's basically kind of like second life but for developers so this full 3D world which you can create and interact with it's in small talk by the way but you can you can right click on objects or change the code of what's happening while it's running and this thing is doing some sort of gene simulation or something I don't know but you can interact with the code directly inside the tool itself the middle one on the bottom I know this is really small and hard to read it's called SubEatEdit which is a commercial product kind of like it's just like a basic text editor but it does collaborative editing and it supports this paradigm pair-wise development much better than we currently do because screen sharing to me that's not pair programming that's screen sharing and we're kind of missing the point if we think that screen sharing is as far as we can go in collaborative development the one on the right is it's a Symbolics product which in Symbolics I believe I don't think they're even around anymore but they develop a list machine in the early 90s I think which was just an awesome concept to start with but again this so didn't really take off but you can edit the kernel while it was running which is kind of crazy the actual operating system kernel the actual tools to do all of that were built into the operating system itself as well as all the libraries really crazy concepts and I think just because of the dynamic nature of Ruby we can do a lot of these things we really can but we need to start focusing some attention on them so in summary thank you