>>ficus kirkpatrick: hi. i'm ficus kirkpatrick.i'm an engineer on the android team. i work on the play store. and i'm here to talk toyou today about something we made that makes it really easy to develop super fast networkedapplications for android. [ applause ]>>ficus kirkpatrick: all right. very good! it's called volley.so what is volley? well, it's a networking
Android qr code library, library. so when i say "volley," you mightbe thinking of something like this, you know, a client sends a request to a server overthe net. it comes back. metaphor complete. message received.but when i named it, i was really thinking of something more like this.mobile app design is getting better and better.
but also more and more demanding for engineers.a lot of current designs are really beautiful, with a lot of rich metadata and tons of images.but these things requires tons of network requests to get all that data and images.and there's a tremendous opportunity to make our apps faster by running those requestsin parallel. so you probably don't want to do quite asmany requests in parallel as shown up here. i think if we stick to the metaphor, thatlooks kind of like a denial of service attack. [ laughter ]>>ficus kirkpatrick: but a volley does make it very easy for you to run your request concurrentlywithout really having to think about threading or networking yourself.sorry, threading or synchronization yourself.
the library comes with most things you needright out of the box, things like accessing json apis or loading images are trivial todo with volley. but it's easy to grow with your needs as well.there's a lot of customization options. you can do your own custom retry and backoff algorithms.you can customize request priority and ordering, and a lot more.it also includes a very powerful request tracing system that we've found invaluable in debuggingand profiling our network activity on the play store.okay. so why do we even need a networking library at all? android already has apachehttp client. it already has http url connection. true, it sure does. people have made tonsof great apps with them.
so here are four apps that i use all the timeon my phone, foursquare, twitter, youtube, and news and weather. these apps are great.i love them. and they have a lot of things in common. they display paginated lists ofitems, typically with a thumbnail for each item. you can click on something and viewan item with more metadata or more images. and there's typically some kind of write operationor post request type thing, like posting a tweet or writing a restaurant review or somethinglike that. and all of these apps had to reinvent severalwheels to do what are, at heart, basically the same tasks.doing response caching or things are fast, getting retry right, executing requests inparallel. everybody pretty much rolls their
own.so what we wanted to do with volley was both provide an interface where you can step upa little bit and think a little less about wire protocols and network transports andmore about logical operations as well as just wrap up a lot of the things that we've learnedin developing production-quality apps at google over the last few years.so volley was designed for exactly the kinds of needs that those applications have. relativelysmall, rpc-like operations, fetching some metadata or getting a profile picture, andput them in the view hierarchy. it's also perfectly fine for doing those samekinds of operations in the background. but it really excels at the intersection of uiand network. it's not for everything, though.
responses are delivered whole in memory. sothat makes for an api that's really easy to use but not a good one for streaming operationslike downloading a video or an mp3. but that's okay. you don't have to use it for everything.there are several apps at google that use volley for their rpcs and use another system,like download manager or whatever, for long-lived, large file download operations.okay. so let's take a simplified example of that kind of common pattern that i talkedabout. i built a sample app that shows a title and a description loaded page by page froma server, with a nice-looking thumbnail image for each item.okay. so we have a server that speaks a relatively simple json protocol. this is, by the way,going to be the basis of my microblogging
startup. so if any of you are angel investors,please come see me afterward. [ laughter ]>>ficus kirkpatrick: the protocol is really simple.we've got -- the outer response is just a list of item json objects with an optionaltoken to retrieve the next page. and each item is simply a title, a description,and an image url all as strings. pretty straightforward. on the client side, again, we have a prettytypical application architecture. we've got an activity. it holds an adapter and a listview.the adapter loads data from the network from the api server and manufactures views forthe listview upon request. okay. so here we are in get view in our adapterin a typical implementation. the standard
trick here is to use the position passed into getview as a hit for when you should download the next page. for example, if you have tenitems in your page, when the listview asks you for the eighth thing, you go ahead andcall load more data to fetch the next page of data.okay. now, how is load more data actually implemented?the usual approach is to use an async task or something like that. so here in do in background,we open an http url connection. we get the input stream for the response data. we makea byte array output stream to copy it into. we use this magical function that i've written100 times in my life to copy it from the input stream to the output stream. and then we passit to the json object constructor for parsing
and return it back.so pretty straightforward conceptually. one thing to note here is that there's actuallya ton of boilerplate crap i had to cut out in order to make this fit on one slide. soyou don't see all the extra async task stuff. and i think more annoyingly, you don't seeall of the try-catch blocks here. you have to try-catch for i/o exception if there'sa network problem or json exception, if there's a parsing error. and then you have to closeyour input stream. and then closing your input stream can throw two. so you need to try-catchthere and have a finally block. and this whole thing is probably twice the size or more ifyou were to see it in something that would compile.finally, we land back in onpostexecute on
the main thread with our parse json object.we pluck out the individual items from that root json object, append them to the listthat backs our adapter, call notify data set changed, and then let the listview call usback to actually make the views. okay. now we're back in getview with somedata. so now we can populate our two text views with the title and description strings.and we now have the image url, so we can kick that off for loading.again, if you're familiar with, this you typically use an async task or something like that.so let's look at a naive implementation of an image-loading async task. here in the constructor,we squirrel away the image view that we want to populate from the image at the given url.and then in background, it's pretty straightforward
from there. you open the http url connection,you get the response stream and pass it off bit map factory for image decoding.again, i had to cut out all of the try-catch, you know, muckety-muck boilerplate stuff.it's all pretty straightforward so far. but tedious.finally, again, we get back onto the main thread in onpostexecute. and we just simplyset image bit map on our image view that we saved in the constructor.okay. so there are actually a whole bunch of problems with the code i just showed you.things ranging from outright bugs to things that are just way too inefficient to ship.so i want to talk about some of the higher-level issues and problems and then discuss volley'sapproach to solving them.
okay. first, the code as written, all networkrequests execute in serial, so one after the other. and this is because you called asynctask.execute,and i'm blaming you for calling it even though i wrote the code. and you didn't call asynctask on execute or executer. or you didn't pass a thread sync executer to async task.or maybe you didn't even know you had to do that.it also means that in order to fetch the next page of data, if the user is scrolling down,you have to wait for all the image requests to complete, because things are scheduledstrictly first in, first out. volley automatically schedules your networkrequests across a thread pool. you can choose the size of the pool or just use the default.we had the best results with four threads
in our testing in the play store. so that'sthe default we chose. volley also supports request prioritization.so you can set your main metadata at high or medium priority, set your images to low,and then if you even -- if you have even a single thread, you never have to wait formore than one image request to complete before you can fetch that next page of data and letthe user continue scrolling down. if you rotate the screen, your activity getsdestroyed, of course. it gets recreated, and you start over from scratch.so that -- in this case, that means reloading absolutely everything from the network.so this isn't a big deal; right? you write your own cache. you -- maybe you put yourimages in a hash map or an lru cache. and,
of course, you still have to do that, whichis tedious. and it also doesn't help you for the next time the user launches your app andyou need to reload everything again because those caches are only going to live for thelifetime of your process. volley provides transparent disk and memorycaching of responses out of the box. so what does transparent caching mean? it just meansthe caller doesn't have to know about the existence of the cache. when there's a cachehit, it simply behaves like a super fast network response.you can provide your own cache implementation, or we have one that you can use in the toolboxright out of the box. and it's very fast. we typically see response times of a few millisecondsfor a typically, you know, 10 to 50k advertised
jpeg image.volley also provides some advanced tools particular to image loading. i'll talk about that ina minute. those of you who have written an app likethis probably saw the bug in my load image async task right off the bat.we've got a bunch of async tasks in flight and they're all loading the images. and maybethe user is scrolling around like crazy and the views are getting recycled in the listview.so by the time the async task actually completes, on post execute runs and we set the bit mapin an image view that doesn't really belong to the async task anymore.okay. so what do you do here? you have a view holder, and you maybe keep the url in it andmake sure that it matches. but then you're
letting a request complete which it doesn'tmatter anymore. you're just going to throw the results away, which makes things slowand it's wasteful. so then maybe you keep track of your async tasks and cancel themwhen you get recycled. again, more work. volley provides a really powerful requestcancellation api where you can easily cancel a single request or you can set blocks orscopes of requests to cancel. or you can just use the network image view that i'm goingto talk about in a second from the toolbox, which does everything for you.okay. one last problem. until gingerbread, http url connection was buggy and flaky. sofor those of you who would try to run this simple code on froyo or before, you mightrun into some problems here.
so you could use apache http client, but that'salso buggy and no longer supported. so that's okay. volley abstracts away the underlyingnetwork transport. so, in fact, if you use our standard setup helper methods, on froyo,you'll automatically get an apache stack, which works best there, and on gingerbreadand above, you automatically get an http connection stack.one really nice thing about this approach is that it doesn't just solve the problemof this kind of varying behavior of these http stacks, but it also creates an opportunity.so say you want to port to square's new okhttp library.>>> whoo! >>ficus kirkpatrick: yeah, i'm a fan.you can just replace that in one place in
your app without having to go do a completerefactor of your code. it's, like, a much more targeted place.okay. so let's look at how we'd implement this map uses volley.there are two main things you interact with in volley, two main classes: request queueand request. request queue is the interface you use for dispatching requests to the network.you can make a request queue on demand if you want, but typically, you'll instead createit early on, at startup time, and keep it around and use it as a singleton.here we also make an image loader. and i'll talk about that in a little bit.okay. here's something dense. here in the volley version of load more data,we make a json object request, which is one
of the standard requests that comes stockin the volley toolbox. and we add it to the queue. we provide it with a listener. anda listener is the standard callback interface you use for receiving your responses. andthe response listener here looks a whole lot like the async task version in onpostexecute.we just parse out the json, append the items to our backing list, and call notify dataset changed. so there are two bigger things i want to pointout here. one is, this is it. this is the whole thing. i went on and on about the boilerplatebefore. the boilerplate is gone. this is the whole thing, end to end.second, the fact that this response listener looks a lot like onpostexecute in the asynctask version means it's easy to port your
app to volley. so you don't have to boil theocean and rewrite your app if you want to start taking advantage of this.okay. getting the image is even easier. we just stowaway the image request in our viewholder and cancel it when we're getting recycled. and image loader, again from the volley toolbox,handles the rest. it provides the memory caching for you. it -- you can even pass in drawablesfor loading or error states. and image loader will take it away from there for you.but maybe you're a programmer after my own heart, which is to say, super lazy.you can just use network image view in the volley toolbox. it's a subclass of image view.you can simply replace your usages of image view in your layouts with this. you call setimage url, and you're done. when it gets detached
from the view hierarchy, the request is automaticallycancelled if it's still in flight. that's it.one -- one subtle but i think pretty awesome thing about volley's image loading code isresponse batching. so if you use image loader or network imageview, the library holds your image responses for a short period of time after -- afterone comes and attempts to batch them together in a single path to the main thread.what this means in practice is that batches and images load in the ui simultaneously.or, for instance, say you're running an animation when you load an image, like, you fade itin. all those things fade in together in sync. and just a little secret sauce on it.okay. so the image stuff, i think, shows that
volley handles the basics out of the box pretty-- pretty strongly. but i also want to show what happens when you run out of the toolboxand you need to roll your own. we have a toolbox, but it doesn't includeeverything. but it's really easy to extend. so let's take a look at making a new typeof request. if you haven't heard of the gson library,it's a json serialization and deserialization library that uses reflection to populate yourjava model objects from json objects. you just make java classes that look like yourjson schema, pass it all to gson, and it figures it out for you.so here's the relevant snippet for a gson adapter for volley. this whole thing is about60 lines of code. this is kind of the meat
of it. you can see there's a gist url on screen.you can look at the whole thing to drop into your app if you want. but it's -- you know,it amounts to, you know, a few lines of code. so we make a string out of the data that comesback from the server. we pass that to gsons from json method along with the class objectof our root response that helps with reflection. we use volley's http header parser helpersfrom the toolbox. and that's it. you can even see we handle those parse errors. and thathappens at the response time, not necessarily in your application code where you're thinkingmore about errors and less about every different type of them that could happen.okay. let's take another look at load more data with that new cool request we just made.so instead of using json object request, we
make a new gson request and pass in the classobject of our list response. and then that's it. it's even smaller. we append the itemsto our backing store and then call notify data set changed.one cool little thing about this is that it means that the parsing actually happens onthe background worker thread instead of in the main thread, like when we do it on onpostexecute,so you get a little bit more parallelism there for free.okay. i want to change gears a little bit and talk about the underlying implementationof volley, kind of how it works, some of the semantics it defines, and give a little lookunder the hood as the implementer, not necessarily as the user.so volley, like i mentioned before, handles
operating a thread pool for you. there's onecache dispatcher thread, there's one or more network dispatcher threads. this diagram showsthe flow of a request through the dispatch pipeline.the blue boxes are the main thread. that's typically going to be your calling code andthe response handler. the green boxes are the cache dispatcher thread. and the orangeboxes are the network dispatcher threads. the cache dispatcher's job is essentiallytriage. it figures out whether we can re- -- service a request entirely from cache orwhether we have to go to the network to get it, such as in the case of a cache miss orperhaps a cache hit, but that's expired. in the case of an expired cache hit, it'salso responsible for forwarding the cache
response to the network dispatchers so thatthey can be reused in the event of an etag match and the server has an opportunity togive you a 304. when we do end up needing to go to the network,like in the case of -- like in the cases i mentioned, the network dispatcher servicesthe requests over http, handles parsing the responses using that parsing code i just showed,and then posts the response back to the main thread as a whole parsed object.as a user of the library, you typically don't have to think about any of this stuff. youenqueue your request from the main thread, you get your responses on the main thread,and that's it. but if you really want to dig in and learnmore about the request pipeline, volley has
a fire hose of debugging information that'savailable for you if you want it. you can just set a system property, and you get verboseoutput of the complete lifetime of all stages of the request dispatch pipeline.here's one random chunk of log i took from my sample app when it was in the middle ofloading a bunch of images. at the top, you can see that this requesttook 443 milliseconds. it was low priority, because it's an image. and it was the 11threquest processed by this dispatcher. each subsequent line below that describesanother step through the dispatch pipeline. you can see on thread one, that's the mainthread, at -- oh, and, by the way, each line shows the incremental time that that steptook.
on the main thread, the request is added tothe queue. 68 milliseconds later, it arrives at the cache dispatcher, which means therewas a little bit of contention for the cache -- the cache triage thread there.the cache dispatcher figures out right away that it's a hit but it's expired, and it forwardsit along to the network dispatcher pool. now, it takes 136 milliseconds to begin processingby the network dispatcher, which is even longer, so there's actually even a bit more contentionfor the network dispatchers than for the cache dispatcher, you can see.it takes -- the http request takes 127 milliseconds. now, this is an expired cache hit for an image,so one thing to note is that this would typically be much faster and you'd get that 304. butthis is a homemade web server i made, and
it's crappy and doesn't have any features.so don't do that. and finally, parsing the request takes about100 milliseconds. in this case, it's an image request, so parsing means image decoding.one side note. 100 milliseconds is actually a pretty long time to decode an image. what'sactually going on here is there's a whole flurry of requests going on and our imagedecoder doesn't allow more concurrent image decodes than there are cpu cores, which isone more thing we found to be optimal in our testing and development on the play store.lastly, we write the response bytes to the cache from the network dispatcher. and wepost the parsed object back to the main thread, and we're done.so this is a pretty advanced feature, and
i don't think most people will use it. butwe have really found it invaluable in digging in and profiling our use in the play store.here's one common thing that you can find using this log.so if you're seeing a large amount of time between post response and done, what thatmeans is that there's a lot of contention for the main thread. if there's a lot of contentionfor the main thread, you're doing too much on the main thread. you can dig in from there.okay. so why do i keep going on about the main thread?obviously, you can't touch the ui from a background thread, so you'd have to post back there anyway.but my obsession with the main thread -- and ask anyone who works with me, it is an obsession-- is about more than just the inconvenience
of having to post a rentable back. when youdo everything on one thread and don't share any state with your workers, synchronizationis implicit. you don't have to think about locking. you don't want to think about locking,because locking is hard. and i'll give you an example.how many people have ever written a block of code that looks like this?a few? okay. me, too.so here's what happens. here we are, our async task is completed. we're in onpostexecute,and something has crashed. we're touching the ui. the ui is dead. but it's way too latein the schedule to figure out why this is happening, so we cram a little null pointercheck in our code. it doesn't crash anymore,
and we head off to the launch party.[ laughter ] >>ficus kirkpatrick: but it's a waste of effort,it's a waste of cpu cycles, it's a waste of network bandwidth, and it's a waste of batteryto allow a request to finish that you're just going to ignore the result of.so it also leaves these warts of, like, if null checks at the top of all your methodsall over your code. i mentioned volley has a powerful cancellationapi. and the main thread interfaces with it like this: volley always delivers responseson the main thread. what that means is that once cancel returns, you can be guaranteedthat your response will not be delivered. so here you can just keep track of all therequests you have in flight and then cancel
them in onstop. you know that when onstopreturns and you're no longer allowed to touch the ui, the request won't be delivered, soyou don't have to check for null at the top of all of your listeners.but you can actually do this with async task, too.so how about this? i mentioned volley lets you set up blocksor scopes of requests. it lets you tag any request with an arbitrary object that youcan use to set up a bulk cancellation scope. so in this example, you tag all the requestswith the activity they belong to, and then you simply pass those to cancel all in onstop,and you can be guaranteed that you're not going to get any more responses.you don't have to use the activity. you could
define a smaller scope, like, say you wantto group all thumbnail requests from one view pager tab and cancel them when you swipe away.you can do that, too. if you really want to go nuts, you can actuallyspecify a custom filter deciding which requests to keep and which requests to cancel. say,for example, you've got a post request in the background and you want to let that go,but you want to cancel all your thumbnails. you can do that, too.okay. so we've covered how easy it is to build an app with volley, or even port your appto volley, and how to grow up from there. just on the porting topic, i want to mention,those of you who have the google i/o 2013 app, that was ported to volley about a monthago, and the whole thing took about half a
day. and it wasn't me who did it, by the way.so you don't have to be an expert. we've again seen those complicated cases definingcustom requests, doing, you know, more advanced cancellation operations. and you can do itwith a lot less code and a lot more functionality than you could in rolling your own. it's easierthan doing it yourself, and you get the benefit of all of those -- all those lessons we'velearned the hard way in developing our apps at google.but it's also faster than doing it yourself. it's also faster than doing it yourself. thegoogle+ team did a benchmark last year after bunch of different networking libraries andvolleyed every single one. they ran on froyo, through ice cream sandwich and jellybean,on different types of hardware. they ran on
edge, 3g, 4g, wi-fi. volley was faster everysingle time, in some cases by a factor of 10.okay. so you're sold. how do you get started? it's pretty easy. just clone the project.we have the repository url up on the screen. from there it's pretty simple. there's aneclipse project -- i guess we will need to add an android studio one -- right there inthe repository. there's also a build.xml file so you can useadd to build yourself a jar or you can just drop your code into your app, any of thosethings. you call volley.newrequestqueue, start addingrequests to the queue and you're off and running. that's pretty much it.anything else? that's all i have. thank you
very much for coming.[ applause ] >>ficus kirkpatrick: i did want to leave timefor q and a, and i will also be at office hours after this or you can hit me up on g+or twitter. so we can take some questions.>>> hi, my name is alexi with (indiscernible). can you talk about size of the in-memory cachefor bitmaps, disk size of the cache for bitmaps? and if you hit the disk cache, on which doesthe bitmap decoding happens? >>ficus kirkpatrick: that's a great question.so the sizes of the caches are completely configurable by you. you can choose the in-memorycache size and the disk cache size separately. all blocking io is done on background threads.we never do blocking io on the main thread.
but it's actually important to do the in-memorycache stuff on the main thread before you ever even get to the http stack. the reasonfor that being that you don't want to leave back into the main looper again. you wantto know immediately that you have your bitmap so that you don't defer, let a layout passhappen and then set your image bitmap and you get a little flicker.does that answer your question? >>> [ inaudible ].>>ficus kirkpatrick: he asked about disk thread versus networking thread.caching -- caching from the disk is all read on the cache thread. so there's serializationat the cache thread. basically things can tend for the cache thread and get stuck ifone thing is reading from the cache. we have
a design for how to split up cache workersor defer the work somewhere else. we just haven't needed it. it's been fast enough.>>> so my name is mike from abex systems. i'm really happy that you guys were able toencapsulate the caching logic. we had troubles trying to do that ourselves. my question isone thing that we need to do is establish different links for cached objects. so fora certain object we determine -- we deem it as static versus dynamic and we cache it fordifferent lengths of time. is that something that will be supported by this volley structure?>>ficus kirkpatrick: yeah. so he's asking about cache ttl basically.so volley's cache implementation on disk respects all the standard http cache shutters. so ifyour server sets this thing expires immediately,
it respects that. it doesn't even get writtento cache. if you say this thing lasts for a day, thisthing lasts for a year, again, the expiration is respected.we don't have -- there's no ttl in memory cache. in our experience things just thrashthrough way too fast, but again you can pass in your own implementation if you need to.>>> hi, ficus. i'm chuck from aweber communications. thank you for this. i've seen a lot of differentapproaches to solving this problem and written a few myself, and one common thing that seemsto occur a lot is the dreaded out of memory exceptions, and particularly when you're dealingwith larger images and lower end devices. so i'm wondering if you saw how volley comparedto other solutions and the number of occurrences
of this and some tips for dealing with thatscenario. >>ficus kirkpatrick: yeah, we definitely struggledwith out of memory errors a lot. it's a tough problem because if you have a lot of memoryto use you can make things fast. the solution that we ended up on that workedreally well for us was a couple of things. one, i mentioned that we don't decode morethings concurrently than there are cpu cores. that actually ends up having a pretty positiveeffect on your kind of instantly measured heap pressure.and the other thing that we do is that we actually in the play store we specify thesize of the in-memory cache as a function of the screen size, which kind of makes sense,right, because you typically want to have
as much in cache to fill three screens' worthof data. as it turns out, devices are typically builtwith the memory to support the screen that they need to fill, so it tends to work outsomewhat coincidentally. i would say this isn't really a volley thing.i think it's a "how to choose your cache size" thing.and so we don't use soft references or weak references. they don't work well. we use hardreferences and set a strong budget. and we are conservative in setting that budget byscaling down with the screen and really with the number of pixels.>>> thanks. >>> hi, my name is mark. i would like to knowwhen is this going to make it into the sdk
manager?and the second part of the question is lots of images, small size, this sounds a lot likethe network protocol spdy. are you planning on integrating spdy into volley?>>ficus kirkpatrick: this is easy to answer. i don't know.it's easy enough to get cloned. i don't think we have a great answer for that, so i willduck that and answer your question about spdy. i'm really excited about spdy. volley was-- it was on my mind when we were designing it.somebody right now is working on putting the okhttp library that square just released -- youmay have seen it -- as an underlying transport stack for volley.i haven't tried ok with spdy yet, but according
to jesse, the author, you can plug spdy intothe back of okhttp, which would pretty much give you spdy in volley.so yes, you can do it. it doesn't work yet, but we intend for it to work really soon.>>> that's great. >>> hey. one of the things that we have foundis that a lot of our activities tend to have a mapping to like an api call. and what wewould like to do is basically make the api call before we do the transition to the activity.a lot of these requests can't actually be cached or shouldn't be cached.is there any way to serialize your request objects?>>ficus kirkpatrick: yes. you can kind of roll your own or the really dirty thing thatwe have done before is you make a separate
request queue with one worker thread and thenthings are first in, first out if they're the same priority.so you can do it. it's -- the api is not optimized for it.>>> okay. any plans to optimize the api for it or add it as a feature?>>ficus kirkpatrick: no. traditionally what we do in the case where we have api callsthat need to be made in the serial is we initiate the second one from the response handler ofthe first one. >>> oh, sorry. by serialize the api call toaction, i mean like parse it so that you can pass it across the activity boundary.>>ficus kirkpatrick: i see. so what i would do in that case, i think, is just pass theurl of your request or the metadata in a parsable
or something, right?>>> right, but then the request isn't going to start until after you make the transitionacross activities. >>ficus kirkpatrick: ah, i see. so i thinkyour option there is going to be to kind of shove it into static somewhere.i don't think there's a great answer to your question.>>> okay. thanks. >>> hi, my name is jonathan. i just have aquick question. in all your examples you were using json request and responses.i was wondering if there was any way to use different types of protocol like xml, forexample? >>ficus kirkpatrick: sure. yeah, i think ijust forgot to mention this.
we use protocol buffers pervasively in theplay store, and the play store runs on volley. yeah, you can use xml, you can -- i used jsonbecause it's easier to read on the slides, but yeah, we use protobuf, you can use xml.we have some things that are done as raw strings. obviously images are all just formats of requests.>>> okay. so it should be pretty easy to plug in whatever we want to use?>>ficus kirkpatrick: very much. and if you look at the gist i showed in the presentationto give you a starting point of writing like your own xml particular request.>>> okay. sounds good. and last question: is there anything built into end all withthree tries in case of request barriers and stuff?>>ficus kirkpatrick: yes, it does have a retry
for you. i didn't have time to cover it rightnow, but can you set a custom retry policy, you can set back off algorithm, all that stuff.>>> all right. sounds great. thanks a lot.
>>ficus kirkpatrick: so i'm going to holdquestions for now. i'll be at office hours if you guys want to talk to me in person.thanks again for coming. please scan the qr code to rate this session unless you didn'tlike it. and thanks very much. [ applause ]