[Lift] Re: jetty/actors performance question tangentially related to lift
Thanks David, I will give Lift Actors a try. Mongodb is supposedly using a connection pool behind the scenes so it isn't supposed to matter whether I create 1 or many connection objects, but I will check the source as I'm not 100% sure. Thanks, Lincoln On Thu, Nov 12, 2009 at 8:05 PM, David Pollak wrote: > This is getting off-topic but... > > I think the issue is that there's a single connection or a single thread > accessing MongoDB. I'd suggest trying a connection pool to MongoDB or to > otherwise see why the MongoDB stuff is not getting parallelized. > > Also, Scala Actors do a lot of fancy stuff in terms of scheduling... you > might want to try the same benchmarks with Lift Actors and see if there's a > difference. > > On Thu, Nov 12, 2009 at 4:48 PM, Lincoln wrote: >> >> Hi, thank you very much for your help so far I really appreciate it. >> Apologies in advance if this thread has become inappropriate since it's not >> directly related to Lift. Just let me know if that's the case and I will >> attempt to solve this problem another way. But, I'm hoping you can help me >> some more... >> Warning: Long email ahead... >> Here's the summary of my load testing results: >> Each request in my load test consists of a single save() to mongodb, >> followed by a findOne() for the record just written and then an arbitrary >> find() for 1000 docs. >> >> I've been experimenting with 3 scenarios: >> >> A single actor processing all requests (this effectively makes things >> single-threaded) >> A pool of 50 actors handling requests that are dispatched to via a round >> robin scheduler >> Create a new actor on demand for every request. >> >> The load I've been using for all tests is 2000 requests at a concurrency >> level of 75. All the results I'm reporting are averages over 3 executions. >> As a benchmark, I ran all these scenarios with the worker stubbed out to >> simply sleep for 100ms and then return. Here are the results when I ran the >> benchmark: >> >> Single shared worker: 7534.439 ms >> Shared Pool of 50 workers: 156.190 ms >> On-demand actor for each request: 127.066 ms >> >> These results are about what I expected. In the single worker case the >> queue quickly backed up and stayed at 74 requests, thus the results were >> about the concurrency level (75) multiplied by the work length (100 ms). >> The shared pool was obviously a huge improvement, but the actor on demand >> was even better because the concurrency level (75) was greater than the >> number of actors in the shared pool (50) and thus there was still some >> queueing in that case. >> I expected when I ran the tests with the mongodb work plugged in that I >> would see results that were roughly proportional to the benchmark. However, >> here's what I got: >> >> Single shared worker: 1968.113 ms >> Shared Pool of 50 workers: 1955.218 ms >> On-demand actor for each request: 1951.352 ms >> >> For the vast majority of these requests, most of the time for the request >> is spent waiting for the actor to receive the work job. This is the case >> regardless of whether I'm using a single actor, a pool, or creating actors >> on demand. In most cases, the mongo work takes 0 - 100 ms but with a >> meaningful minority in the 100 - 300ms range. I think this means the JVM >> must be busy with something else while that waiting is happening. >> I guess it makes sense that the single-threaded case goes faster since >> most of the time the mongodb operations take far less than 100 ms. However, >> I don't understand why I'm not seeing proportional improvement in the pooled >> and on-demand scenarios. >> Here is the method I'm using to create my actors, whether it be 1, the >> pool of 50, or a new one on demand every time: >> def worker(n: Int) = actor { >> loop { >> react { >> case msg @ LoadReq(timer, stats, cont) => >> timer.split("react") >> stats("mailboxSize") = mailboxSize.toLong >> val coll = staticColl >> val dbo = ( >> _msg -> "blah blah blah" << >> _event -> "blah blah blah" << >> _user -> "blah blah blah" << >> _name -> "Lincoln" >> ) >> coll.save(dbo) >> timer.split("save") >> coll.findOne(_name -> "Lincoln") >> timer.split("findOne") >> val res = coll.find().limit(1000).toArray >> timer.split("findAll") >&
[Lift] Re: jetty/actors performance question tangentially related to lift
Hi, thank you very much for your help so far I really appreciate it. Apologies in advance if this thread has become inappropriate since it's not directly related to Lift. Just let me know if that's the case and I will attempt to solve this problem another way. But, I'm hoping you can help me some more... Warning: Long email ahead... Here's the summary of my load testing results: Each request in my load test consists of a single save() to mongodb, followed by a findOne() for the record just written and then an arbitrary find() for 1000 docs. I've been experimenting with 3 scenarios: 1. A single actor processing all requests (this effectively makes things single-threaded) 2. A pool of 50 actors handling requests that are dispatched to via a round robin scheduler 3. Create a new actor on demand for every request. The load I've been using for all tests is 2000 requests at a concurrency level of 75. All the results I'm reporting are averages over 3 executions. As a benchmark, I ran all these scenarios with the worker stubbed out to simply sleep for 100ms and then return. Here are the results when I ran the benchmark: - Single shared worker: 7534.439 ms - Shared Pool of 50 workers: 156.190 ms - On-demand actor for each request: 127.066 ms These results are about what I expected. In the single worker case the queue quickly backed up and stayed at 74 requests, thus the results were about the concurrency level (75) multiplied by the work length (100 ms). The shared pool was obviously a huge improvement, but the actor on demand was even better because the concurrency level (75) was greater than the number of actors in the shared pool (50) and thus there was still some queueing in that case. I expected when I ran the tests with the mongodb work plugged in that I would see results that were roughly proportional to the benchmark. However, here's what I got: - Single shared worker: 1968.113 ms - Shared Pool of 50 workers: 1955.218 ms - On-demand actor for each request: 1951.352 ms For the vast majority of these requests, most of the time for the request is spent waiting for the actor to receive the work job. This is the case regardless of whether I'm using a single actor, a pool, or creating actors on demand. In most cases, the mongo work takes 0 - 100 ms but with a meaningful minority in the 100 - 300ms range. I think this means the JVM must be busy with something else while that waiting is happening. I guess it makes sense that the single-threaded case goes faster since most of the time the mongodb operations take far less than 100 ms. However, I don't understand why I'm not seeing proportional improvement in the pooled and on-demand scenarios. Here is the method I'm using to create my actors, whether it be 1, the pool of 50, or a new one on demand every time: def worker(n: Int) = actor { loop { react { case msg @ LoadReq(timer, stats, cont) => timer.split("react") stats("mailboxSize") = mailboxSize.toLong val coll = staticColl val dbo = ( _msg -> "blah blah blah" << _event -> "blah blah blah" << _user -> "blah blah blah" << _name -> "Lincoln" ) coll.save(dbo) timer.split("save") coll.findOne(_name -> "Lincoln") timer.split("findOne") val res = coll.find().limit(1000).toArray timer.split("findAll") // timer.split("sleep") cont.setAttribute(Base.CONTINUATION_RESP, LoadResp(timer, stats)) cont.resume case other => trace("worker discarded: "+other) } } } I took a kill -3 while my load test was running and I saw a lot of these: "qtp1491907201-104" prio=5 tid=0x000102278800 nid=0x153199000 runnable [0x000153198000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000108bca370> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1963) at org.eclipse.jetty.util.BlockingArrayQueue.poll(BlockingArrayQueue.java:319) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:450) at java.lang.Thread.run(Thread.java:637) I also used jstat throughout: Timestamp S0 S1 E O P YGC YGCTFGC FGCT GCT 161.8 100.00 0.00 0.00 68.15 60.181029.215 2 0.0229.237 166.8 100.00 0.00 10.04 28.97 60.32134 12.083 4 0.049 12.132 171.8 100.00 0.00 60.79 68.23 60.06172 14.904 4 0.049 14.952 176.8 0.00 100.00 100.00 4.04 59.87191 17.437 7 1.362 18.799 181.8 100.00 0.00
[Lift] Re: jetty/actors performance question tangentially related to lift
Thanks for the feedback David... I have also created a pool of actors and dispatch requests round-robin style to it. Oddly enough, I see absolutely no difference in the performance characteristics - in both cases 95% of the time is spent between the suspend and the actor receiving the request, but the mailbox never grows past a size of 1 or 2. I will try and send along a simplified version of my code to illustrate what I'm doing. Thanks, Lincoln On Sun, Nov 8, 2009 at 11:02 PM, David Pollak wrote: > If you have all your requests going to 1 actor, then you've reduced your > application to a single threaded app. > > If you're using Scala Actors, there are all kinds of wacky things that > happen with the Fork-Join library that the Actors use for scheduling and a > whole lot of knobs to turn to get the scheduling right depending on your > number of CPUs, etc. > > But, at the end of the day, if you're just pushing work from one thread (the > thread that the HTTP request comes in on) to another thread (the thread > that's waiting for the RDBMS request), you're not saving any time or > threads, in fact you're only increasing the amount of thrash between > scheduling the Actor, suspending the HTTP request thread, etc. > > But, without seeing your code, it's hard to give you a better analysis. > > On Sun, Nov 8, 2009 at 7:08 PM, Lincoln wrote: >> >> Hi, >> >> Currently I have a jetty webapp that uses continuations and actors to >> scale to many connections. While this isn't a lift question per se I >> was hoping the folks on this list could help since it's my >> understanding that Lift does similar stuff under certain setups. >> >> Basically, the functionality that I'm testing receives a request, >> suspends it via jetty continuations, and fires it off to an actor for >> processing. Once the work is done (some benchmark database requests, >> usually on the order of 10 to 100ms) the continuation is resumed and >> results are returned. >> >> As I scale up to 1000+ concurrents in apache benchmark, I notice that >> the vast majority of time from receipt of the request to response, is >> between when the continuation is suspended and when my actor receives >> the message. This strikes me as bizarre since I'm monitoring the >> mailbox and it never grows to a size larger than 1 or 2. It gets to >> the point where requests are taking 10 seconds to come back and 9.5 of >> those seconds are my actor waiting to receive the work request. >> >> Throughout the load test the database does not become stressed. >> >> Any thoughts on this? I guess I'm hoping there is something basic >> that I'm doing wrong. Just in case, I've tried creating an actor pool >> to receive the work requests but that apparently has no effect on the >> results. >> >> My only speculation at this point is that perhaps the reason messages >> are taking so long to get to my actor is because jetty itself is >> overloaded trying to queue requests but that is just a guess. >> >> Thanks, >> Lincoln >> >> > > > > -- > Lift, the simply functional web framework http://liftweb.net > Beginning Scala http://www.apress.com/book/view/1430219890 > Follow me: http://twitter.com/dpp > Surf the harmonics > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] jetty/actors performance question tangentially related to lift
Hi, Currently I have a jetty webapp that uses continuations and actors to scale to many connections. While this isn't a lift question per se I was hoping the folks on this list could help since it's my understanding that Lift does similar stuff under certain setups. Basically, the functionality that I'm testing receives a request, suspends it via jetty continuations, and fires it off to an actor for processing. Once the work is done (some benchmark database requests, usually on the order of 10 to 100ms) the continuation is resumed and results are returned. As I scale up to 1000+ concurrents in apache benchmark, I notice that the vast majority of time from receipt of the request to response, is between when the continuation is suspended and when my actor receives the message. This strikes me as bizarre since I'm monitoring the mailbox and it never grows to a size larger than 1 or 2. It gets to the point where requests are taking 10 seconds to come back and 9.5 of those seconds are my actor waiting to receive the work request. Throughout the load test the database does not become stressed. Any thoughts on this? I guess I'm hoping there is something basic that I'm doing wrong. Just in case, I've tried creating an actor pool to receive the work requests but that apparently has no effect on the results. My only speculation at this point is that perhaps the reason messages are taking so long to get to my actor is because jetty itself is overloaded trying to queue requests but that is just a guess. Thanks, Lincoln --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: json extraction problem
Cool, thanks Joni. I'll give it a try. On Thu, Oct 1, 2009 at 2:36 AM, Joni Freeman wrote: > > Hi, > > I pasted this to scala console and it worked. I am pretty sure that > the problem is that your case classes are inner classes. Inner classes > get one extra implicit constructor parameter, a reference to the outer > class (same way as in Java). You need to move those case classes away > from enclosing class (to an object or package etc.). > > The error message is very bad in this case. I will fix it. > > Cheers Joni > > On Oct 1, 7:49 am, Lincoln wrote: > > Hi, I've been playing around with lift-json and I keep running into basic > > problems. I'm hoping someone can point out my mistake. > > I'm using "net.liftweb" % "lift-json" % "1.1-M5" > > > > Here's the code I'm trying to run: > > > > implicit val formats = net.liftweb.json.DefaultFormats > > case class Name(first: String, last: String) > > case class User(name: Name, email: String) > > import net.liftweb.json.JsonParser._ > > val u = { > > import JsonDSL._ > > ("name" -> > > ("first" -> "Lincoln") ~ > > ("last" -> "Hochberg") > > ) ~ > > ("email" -> "linxbet...@gmail.com")} > > > > val json = JsonDSL.pretty(JsonAST.render(u)) > > val jsonAST = JsonParser.parse(json) > > val user = jsonAST.extract[User] > > > > This blows up with the following exception: > > > > net.liftweb.json.MappingException: Parsed JSON values do not match with > > class constructor > > args= > > arg types= > > constructor=public > > pkg.TestSpec$$anonfun$1$$anonfun$apply$1(pkg.TestSpec$$anonfun$1) > > at > > > net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$fail(Extraction.scala:151) > > at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:72) > > at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) > > at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) > > at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) > > at scala.List.flatMap(List.scala:1132) > > at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) > > at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) > > at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) > > at scala.List.flatMap(List.scala:1132) > > at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) > > at net.liftweb.json.Extraction$.extract0(Extraction.scala:109) > > at net.liftweb.json.Extraction$.extract(Extraction.scala:60) > > at net.liftweb.json.JsonAST$JValue.extract(Json.scala:109) > > at > > > com.hotpotato.core.ops.TestSpec$$anonfun$1$$anonfun$apply$1.apply(TestSpec.scala:48) > > at > > > com.hotpotato.core.ops.TestSpec$$anonfun$1$$anonfun$apply$1.apply(TestSpec.scala:14) > > at > > > org.specs.specification.ExampleExecution$$anonfun$3$$anonfun$apply$1.apply(Example.scala:207) > > at org.specs.specification.Example.execute(Example.scala:121) > > at > > > org.specs.specification.ExampleLifeCycle$class.executeTest(ExampleLifeCycle.scala:20) > > at org.specs.Specification.executeTest(Specification.scala:28) > > at org.specs.specification.Sus.executeTest(Sus.scala:147) > > at > > > org.specs.specification.ExampleExecution$$anonfun$3.apply(Example.scala:207) > > at > > > org.specs.specification.ExampleExecution$$anonfun$3.apply(Example.scala:194) > > at > > > org.specs.specification.ExampleExecution$$anonfun$2.apply(Example.scala:185) > > at org.specs.specification.ExampleExecution.execute(Example.scala:227) > > at org.specs.specification.Example.execute(Example.scala:117) > > at org.specs.specification.Example.errors(Example.scala:143) > > at org.specs.specification.Sus$$anonfun$successes$1.apply(Sus.scala:122) > > at org.specs.specification.Sus$$anonfun$successes$1.apply(Sus.scala:122) > > at scala.List.filter(List.scala:859) > > at org.specs.specification.Sus.successes(Sus.scala:122) > > at > > > org.specs.Specification$$anonfun$successes$1.apply(Specification.scala:84) > > at > > > org.specs.Specification$$anonfun$successes$1.apply(Specification.scala:84) > > at scala.List.flatMap(List.scala:1132) > > at org.specs.Specification.successes(Specification.scala:84) > > at > > > sbt.impl.SpecsRunner.sbt$impl$SpecsRunner$$reportSpecification(TestFrameworkImpl.scala:140) > > at sbt.impl.SpecsRunner.runTest(TestFrameworkImpl.scala:123) > > at sbt.BasicTestRu
[Lift] json extraction problem
Hi, I've been playing around with lift-json and I keep running into basic problems. I'm hoping someone can point out my mistake. I'm using "net.liftweb" % "lift-json" % "1.1-M5" Here's the code I'm trying to run: implicit val formats = net.liftweb.json.DefaultFormats case class Name(first: String, last: String) case class User(name: Name, email: String) import net.liftweb.json.JsonParser._ val u = { import JsonDSL._ ("name" -> ("first" -> "Lincoln") ~ ("last" -> "Hochberg") ) ~ ("email" -> "linxbet...@gmail.com") } val json = JsonDSL.pretty(JsonAST.render(u)) val jsonAST = JsonParser.parse(json) val user = jsonAST.extract[User] This blows up with the following exception: net.liftweb.json.MappingException: Parsed JSON values do not match with class constructor args= arg types= constructor=public pkg.TestSpec$$anonfun$1$$anonfun$apply$1(pkg.TestSpec$$anonfun$1) at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$$fail(Extraction.scala:151) at net.liftweb.json.Extraction$.newInstance$1(Extraction.scala:72) at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) at scala.List.flatMap(List.scala:1132) at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) at net.liftweb.json.Extraction$$anonfun$1.apply(Extraction.scala:84) at scala.List.flatMap(List.scala:1132) at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) at net.liftweb.json.Extraction$.extract0(Extraction.scala:109) at net.liftweb.json.Extraction$.extract(Extraction.scala:60) at net.liftweb.json.JsonAST$JValue.extract(Json.scala:109) at com.hotpotato.core.ops.TestSpec$$anonfun$1$$anonfun$apply$1.apply(TestSpec.scala:48) at com.hotpotato.core.ops.TestSpec$$anonfun$1$$anonfun$apply$1.apply(TestSpec.scala:14) at org.specs.specification.ExampleExecution$$anonfun$3$$anonfun$apply$1.apply(Example.scala:207) at org.specs.specification.Example.execute(Example.scala:121) at org.specs.specification.ExampleLifeCycle$class.executeTest(ExampleLifeCycle.scala:20) at org.specs.Specification.executeTest(Specification.scala:28) at org.specs.specification.Sus.executeTest(Sus.scala:147) at org.specs.specification.ExampleExecution$$anonfun$3.apply(Example.scala:207) at org.specs.specification.ExampleExecution$$anonfun$3.apply(Example.scala:194) at org.specs.specification.ExampleExecution$$anonfun$2.apply(Example.scala:185) at org.specs.specification.ExampleExecution.execute(Example.scala:227) at org.specs.specification.Example.execute(Example.scala:117) at org.specs.specification.Example.errors(Example.scala:143) at org.specs.specification.Sus$$anonfun$successes$1.apply(Sus.scala:122) at org.specs.specification.Sus$$anonfun$successes$1.apply(Sus.scala:122) at scala.List.filter(List.scala:859) at org.specs.specification.Sus.successes(Sus.scala:122) at org.specs.Specification$$anonfun$successes$1.apply(Specification.scala:84) at org.specs.Specification$$anonfun$successes$1.apply(Specification.scala:84) at scala.List.flatMap(List.scala:1132) at org.specs.Specification.successes(Specification.scala:84) at sbt.impl.SpecsRunner.sbt$impl$SpecsRunner$$reportSpecification(TestFrameworkImpl.scala:140) at sbt.impl.SpecsRunner.runTest(TestFrameworkImpl.scala:123) at sbt.BasicTestRunner.run(TestFramework.scala:38) at sbt.TestFramework$$anonfun$7$$anonfun$apply$8.runTest$1(TestFramework.scala:136) at sbt.TestFramework$$anonfun$7$$anonfun$apply$8$$anonfun$apply$9.apply(TestFramework.scala:147) at sbt.TestFramework$$anonfun$7$$anonfun$apply$8$$anonfun$apply$9.apply(TestFramework.scala:147) at sbt.NamedTestTask.run(TestFramework.scala:57) at sbt.ScalaProject$$anonfun$sbt$ScalaProject$$toTask$1.apply(ScalaProject.scala:167) at sbt.ScalaProject$$anonfun$sbt$ScalaProject$$toTask$1.apply(ScalaProject.scala:167) at sbt.TaskManager$Task.invoke(TaskManager.scala:62) at sbt.impl.RunTask.runTask(RunTask.scala:78) at sbt.impl.RunTask.sbt$impl$RunTask$$runIfNotRoot(RunTask.scala:63) at sbt.impl.RunTask$$anonfun$runTasksExceptRoot$3.apply(RunTask.scala:49) at sbt.impl.RunTask$$anonfun$runTasksExceptRoot$3.apply(RunTask.scala:49) at sbt.Distributor$Run$Worker$$anonfun$2.apply(ParallelRunner.scala:130) at sbt.Distributor$Run$Worker$$anonfun$2.apply(ParallelRunner.scala:130) at sbt.Control$.trapUnit(Control.scala:19) at sbt.Distributor$Run$Worker.run(ParallelRunner.scala:130) Any ideas? Thanks, Lincoln --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: lift-json
Got it. Thanks for the info. I was afraid I was doing something wrong. Thanks, Lincoln On Sun, Sep 13, 2009 at 9:48 AM, Joni Freeman wrote: > > Hi, > > Your example should work if you take the val away from your case > class: > > case class MyName(first:String, last:String) > case class MyUser(id:String, name:MyName, url:String) > > The reflection code currently fails to find the primary constructor of > case class if there's extra fields. This will hopefully be fixed some > day when the reflection story of Scala gets better (using Java > reflection is very awkward). > > Cheers Joni > > On Sep 13, 7:55 am, Lincoln wrote: > > Sorry, here's the full code I'm using: > > > > case class MyName(first:String, last:String) > > case class MyUser(id:String, name:MyName, url:String) { > > val wtf = "wtf" > > > > } > > > > implicit val formats = net.liftweb.json.DefaultFormats > > val json = > > ("id" -> me.id) ~ > > ("name" -> > > ("first" -> me.name.first) ~ > > ("last" -> me.name.last) > > ) ~ > > ("url" -> me.url) > > val output = JsonDSL.pretty(render(json)) > > val jsonCopy = parse(output) > > val user = jsonCopy.extract[MyUser] > > println("user = "+user) > > > > On Sun, Sep 13, 2009 at 12:07 AM, linxbetter > wrote: > > > Hello, I saw a post about lift-json on the scala-user list so I > > > decided to check it out. I was particularly interested in the ability > > > to call something along the lines of json.extract[MyClass]. I set up > > > a little test case for this though, and apparently having a val of any > > > sort in my case class causes the below exception. Any thoughts? > > > > > My classes looked like this: > > > case class MyName(first:String, last:String) > > > case class MyUser(id:String, name:MyName, url:String) { > > > val wtf = "wtf" > > > } > > > > > And the output of my test > > > > > [info] lift-json should > > > [info] x do pain-free json conversion on nested objects > > > net.liftweb.json.MappingException: Expected JField but got JNothing, > > > json='JField(name,JObject(List(JField(first,JString(Lincoln)), JField > > > (last,JString(Hochberg)', path='wtf' > > >at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$ > > > $fail(Extraction.scala:151) > > >at net.liftweb.json.Extraction$.fieldValue$1(Extraction.scala: > > > 106) > > >at net.liftweb.json.Extraction$.build$1(Extraction.scala:78) > > >at net.liftweb.json.Extraction$$anonfun$1.apply > > > (Extraction.scala:84) > > >at net.liftweb.json.Extraction$$anonfun$1.apply > > > (Extraction.scala:84) > > >at scala.List.flatMap(List.scala:1132) > > >at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) > > >at net.liftweb.json.Extraction$$anonfun$1.apply > > > (Extraction.scala:84) > > >at net.liftweb.json.Extraction$$anonfun$1.apply > > > (Extraction.scala:84) > > >at scala.List.flatMap(List.scala:1132) > > >at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) > > >at net.liftweb.json.Extraction$.extract0(Extraction.scala:109) > > >at net.liftweb.json.Extraction$.extract(Extraction.scala:60) > > >at net.liftweb.json.JsonAST$JValue.extract(Json.scala:109) > > >at com.hotpotato.core.SerializationSpec$$anonfun$1$$anonfun > > > $apply$1.apply(SerializationSpec.scala:87) > > >at com.hotpotato.core.SerializationSpec$$anonfun$1$$anonfun > > > $apply$1.apply(SerializationSpec.scala:69) > > >at org.specs.specification.ExampleExecution$$anonfun$3$$anonfun > > > $apply$1.apply(Example.scala:207) > > >at org.specs.specification.Example.execute(Example.scala:121) > > >at org.specs.specification.ExampleLifeCycle$class.executeTest > > > (ExampleLifeCycle.scala:20) > > >at org.specs.Specification.executeTest(Specification.scala:28) > > >at org.specs.specification.Sus.executeTest(Sus.scala:147) > > >at org.specs.specification.ExampleExecution$$anonfun$3.apply > > > (Example.scala:207) > > >at org.specs.specification.ExampleExecution$$anonfun$3.apply > > > (Example.scala:194) > > >at org.specs.specification.ExampleExecution$$anonfun$2.apply
[Lift] Re: lift-json
Sorry, here's the full code I'm using: case class MyName(first:String, last:String) case class MyUser(id:String, name:MyName, url:String) { val wtf = "wtf" } implicit val formats = net.liftweb.json.DefaultFormats val json = ("id" -> me.id) ~ ("name" -> ("first" -> me.name.first) ~ ("last" -> me.name.last) ) ~ ("url" -> me.url) val output = JsonDSL.pretty(render(json)) val jsonCopy = parse(output) val user = jsonCopy.extract[MyUser] println("user = "+user) On Sun, Sep 13, 2009 at 12:07 AM, linxbetter wrote: > Hello, I saw a post about lift-json on the scala-user list so I > decided to check it out. I was particularly interested in the ability > to call something along the lines of json.extract[MyClass]. I set up > a little test case for this though, and apparently having a val of any > sort in my case class causes the below exception. Any thoughts? > > My classes looked like this: > case class MyName(first:String, last:String) > case class MyUser(id:String, name:MyName, url:String) { > val wtf = "wtf" > } > > And the output of my test > > [info] lift-json should > [info] x do pain-free json conversion on nested objects > net.liftweb.json.MappingException: Expected JField but got JNothing, > json='JField(name,JObject(List(JField(first,JString(Lincoln)), JField > (last,JString(Hochberg)', path='wtf' >at net.liftweb.json.Extraction$.net$liftweb$json$Extraction$ > $fail(Extraction.scala:151) >at net.liftweb.json.Extraction$.fieldValue$1(Extraction.scala: > 106) >at net.liftweb.json.Extraction$.build$1(Extraction.scala:78) >at net.liftweb.json.Extraction$$anonfun$1.apply > (Extraction.scala:84) >at net.liftweb.json.Extraction$$anonfun$1.apply > (Extraction.scala:84) >at scala.List.flatMap(List.scala:1132) >at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) >at net.liftweb.json.Extraction$$anonfun$1.apply > (Extraction.scala:84) >at net.liftweb.json.Extraction$$anonfun$1.apply > (Extraction.scala:84) >at scala.List.flatMap(List.scala:1132) >at net.liftweb.json.Extraction$.build$1(Extraction.scala:84) >at net.liftweb.json.Extraction$.extract0(Extraction.scala:109) >at net.liftweb.json.Extraction$.extract(Extraction.scala:60) >at net.liftweb.json.JsonAST$JValue.extract(Json.scala:109) >at com.hotpotato.core.SerializationSpec$$anonfun$1$$anonfun > $apply$1.apply(SerializationSpec.scala:87) >at com.hotpotato.core.SerializationSpec$$anonfun$1$$anonfun > $apply$1.apply(SerializationSpec.scala:69) >at org.specs.specification.ExampleExecution$$anonfun$3$$anonfun > $apply$1.apply(Example.scala:207) >at org.specs.specification.Example.execute(Example.scala:121) >at org.specs.specification.ExampleLifeCycle$class.executeTest > (ExampleLifeCycle.scala:20) >at org.specs.Specification.executeTest(Specification.scala:28) >at org.specs.specification.Sus.executeTest(Sus.scala:147) >at org.specs.specification.ExampleExecution$$anonfun$3.apply > (Example.scala:207) >at org.specs.specification.ExampleExecution$$anonfun$3.apply > (Example.scala:194) >at org.specs.specification.ExampleExecution$$anonfun$2.apply > (Example.scala:185) >at org.specs.specification.ExampleExecution.execute > (Example.scala:227) >at org.specs.specification.Example.execute(Example.scala:117) >at org.specs.specification.Example.errors(Example.scala:143) >at org.specs.specification.Sus$$anonfun$successes$1.apply > (Sus.scala:122) >at org.specs.specification.Sus$$anonfun$successes$1.apply > (Sus.scala:122) >at scala.List.filter(List.scala:859) >at org.specs.specification.Sus.successes(Sus.scala:122) >at org.specs.Specification$$anonfun$successes$1.apply > (Specification.scala:84) >at org.specs.Specification$$anonfun$successes$1.apply > (Specification.scala:84) >at scala.List.flatMap(List.scala:1132) >at org.specs.Specification.successes(Specification.scala:84) >at sbt.impl.SpecsRunner.sbt$impl$SpecsRunner$ > $reportSpecification(TestFrameworkImpl.scala:140) >at sbt.impl.SpecsRunner.runTest(TestFrameworkImpl.scala:123) >at sbt.BasicTestRunner.run(TestFramework.scala:38) >at sbt.TestFramework$$anonfun$7$$anonfun$apply$8.runTest$1 > (TestFramework.scala:136) >at sbt.TestFramework$$anonfun$7$$anonfun$apply$8$$anonfun$apply > $9.apply(TestFramework.scala:147) >at sbt.TestFramework$$anonfun$7$$anonfun$apply$8$$anonfun$apply > $9.apply(TestFr
[Lift] Re: Google App Engine
This looks like the thread: http://www.nabble.com/-scala--Google-App-Engine-for-Scala%21-td22944265.html Linc. On 08/04/2009, at 4:53 PM, Timothy Perrett wrote: > > Can you fwd to the lift list for those of us not on the main scala > mailing lists? > > Thanks, Tim > > On Apr 8, 3:14 pm, David Pollak wrote: >> See my response on the scala list > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Lift" group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---