<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9099290662356800026</id><updated>2012-02-16T10:49:30.283-08:00</updated><category term='ruby'/><category term='android'/><category term='jruby'/><category term='how-to'/><category term='terracotta'/><category term='ehcache'/><category term='scalability'/><category term='samsung epic'/><category term='rails'/><title type='text'>Unweaving the Rainbow</title><subtitle type='html'>Jason Voegele&amp;#39;s personal blog, featuring occasional ramblings about technology, science &amp;amp; skepticism, or whatever else comes to mind.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jvoegele.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9099290662356800026/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jvoegele.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jason Voegele</name><uri>http://www.blogger.com/profile/16938133385202930039</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://4.bp.blogspot.com/_XMi6F4SX8RQ/TLxSUt_z7DI/AAAAAAAAABk/BlQUMHop_Ys/S220/jason.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9099290662356800026.post-7012834099915148362</id><published>2010-11-15T10:35:00.000-08:00</published><updated>2012-02-09T04:14:26.881-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='ehcache'/><title type='text'>Ehcache for JRuby and Rails: Now with more flavor and fewer calories</title><content type='html'>&lt;p&gt;In my last blog post I discussed how you can achieve &lt;a href="http://jvoegele.blogspot.com/2010/10/terabyte-scale-for-jruby-and-rails.html"&gt;Terabyte scale for JRuby and Rails&lt;/a&gt;, and judging from the response I received this is a topic of some interest to Ruby and Rails developers.  In that post I explained how it is possible to use &lt;a href="http://www.ehcache.org/"&gt;Ehcache&lt;/a&gt; as a Rails caching provider, or use its API directly from any JRuby application.  Since that time, I've done some further work to make Ehcache integration with JRuby and Rails more robust and production ready.  In this post I'll describe what's new and improved, including complete coverage of the Ehcache Java API.  In a followup post I will discuss how to utilize the new Ehcache JRuby and Rails integration for large scale enterprise applications, including fully coherent &lt;a href="http://ehcache.org/documentation/get-started/about-distributed-cache"&gt;distributed caching with Ehcache and Terracotta&lt;/a&gt;, and also how to use &lt;a href="http://www.terracotta.org/bigmemory"&gt;BigMemory for Enterprise Ehcache&lt;/a&gt; to make sure your application can handle any load you can throw at it.&lt;/p&gt;&lt;h2&gt;More Flavor&lt;/h2&gt;&lt;p&gt;In previous iterations of jruby-ehcache we took the approach of providing Ruby wrapper classes to encapsulate the functionality of Ehcache behind a nice Ruby interface.  This had the advantage of making the API more idiomatic to Ruby, but it also meant that we did not provide full API coverage and that any time the Ehcache API changed we also had to update our Ruby wrapper API to accommodate the changes.  As you can imagine, we weren't entirely satisfied with this approach and so went in search of a better mechanism.  It turns out that JRuby's Java integration combined with Ruby's dynamic open classes provide exactly what we need for this.&lt;/p&gt;&lt;p&gt;The Java integration provided by JRuby makes it incredibly easy to use any Java API from Ruby code.  All that is required is adding a simple &lt;code&gt;require 'java'&lt;/code&gt; to your Ruby code and the whole of the Java landscape is opened up to you.  We built on top of this in the latest jruby-ehcache gem by having the gem automatically set up the CLASSPATH and invoke &lt;code&gt;require 'java'&lt;/code&gt;for you, and now with one line of code you instantly have the complete Ehcache API available to your Ruby application:&lt;/p&gt;&lt;pre class="brush:ruby"&gt;require 'ehcache'&lt;/pre&gt;&lt;p&gt;With that one line of code in place, you can now use any part of the Ehcache API just as you would in a Java application, and JRuby even provides some extra niceties to make the Java API more Ruby-friendly:&lt;/p&gt;&lt;pre class="brush:ruby"&gt;require 'ehcache'&lt;br /&gt;  cache_manager = Java::NetSfEhcache::CacheManager.new&lt;br /&gt;  cache = cache_manager.getCache("myCache")&lt;br /&gt;  cache.put("answer", "42")&lt;br /&gt;  answer = cache.get("answer")  # Returns Ehcache Element object&lt;br /&gt;  puts "Answer: #{answer.value}"&lt;br /&gt;  question = cache.get("question") # Returns nil&lt;br /&gt;  if question&lt;br /&gt;    puts "Question: #{question.value}"&lt;br /&gt;  else&lt;br /&gt;    puts "I don't know the question"&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;I won't cover every detail of JRuby Java integration (see &lt;a href="http://kenai.com/projects/jruby/pages/CallingJavaFromJRuby"&gt;Calling Java From Ruby&lt;/a&gt; on the JRuby wiki for full details), but I do want to point out a couple of important details.  First, notice how Java classes are referenced from Ruby code.  The expression &lt;code&gt;Java::NetSfEhcache::CacheManager&lt;/code&gt; is a reference to the Java class &lt;code&gt;net.sf.ehcache.CacheManager&lt;/code&gt;.  More generally, any Java class can be accessed within the &lt;code&gt;Java&lt;/code&gt; module by transforming the package path by removing the dots and converting to CamelCase.  Second, JRuby performs some magic to convert Java method names  and JavaBeans property accessors to more Ruby-like equivalents.  Thus, you can call the &lt;code&gt;getCache&lt;/code&gt; method in any of three ways: &lt;code&gt;getCache&lt;/code&gt;, &lt;code&gt;get_cache&lt;/code&gt;, or simply &lt;code&gt;cache&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;That is nice enough, but as any good Rubyist will attest, Java APIs tend to be bloated and difficult to use compared to an equivalent Ruby API.  Luckily, we can take advantage of Ruby's dynamic nature and support for open classes to provide a much more Rubyesque API without sacrificing full access to the underlying Java API.  For instance, it would be nice if we could use the familiar array access notation to access cache entries, and while we're at it couldn't we also do away with the Ehcache Element object and just access the cache entry value directly?  Let's see how this is done.&lt;/p&gt;&lt;pre class="brush:ruby"&gt;class Java::NetSfEhcache::Cache&lt;br /&gt;    # Gets an element value from the cache.  Unlike the #get method, this method&lt;br /&gt;    # returns the element value, not the Element object.&lt;br /&gt;    def [](key)&lt;br /&gt;      element = self.get(key)&lt;br /&gt;      element ? element.value : nil&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # Later...&lt;br /&gt;  forty_two = cache['answer']   # Returns the value, not the Element object&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Here we open up the &lt;code&gt;net.sf.ehcache.Cache&lt;/code&gt; class and add our own custom method to it to provide array access notation.  Note that this is not inheritance and we are actually modifying the Cache class directly, so you can now use the &lt;code&gt;[]&lt;/code&gt; operator on any &lt;code&gt;Cache&lt;/code&gt; object, whether you created it yourself in Ruby code or it was created deep in the bowels of some legacy Java code.  The world is yours.&lt;/p&gt;&lt;p&gt;Another bit of Ruby goodness we've added in the latest version is to make the &lt;code&gt;Ehcache::CacheManager&lt;/code&gt; and &lt;code&gt;Ehcache::Cache&lt;/code&gt; classes include the Ruby &lt;code&gt;Enumerable&lt;/code&gt; module.  Anyone who's done a significant amount of Ruby programming knows how powerful this module is, but for those who might not be familiar with it let's have a look at a few example usages that illustrate it's power.&lt;/p&gt;&lt;pre class="brush:ruby"&gt;# Find all cache entries with time to live greater than one minute.&lt;br /&gt;  cache.find_all {|e| e.ttl &amp;gt; 60}&lt;br /&gt;&lt;br /&gt;  # Which cache entry has the largest time to live value?&lt;br /&gt;  cache.max {|e1, e2| e1.ttl &amp;lt;=&amp;gt; e2.ttl}&lt;br /&gt;&lt;br /&gt;  # Are all cache entries strings?&lt;br /&gt;  cache.all? {|e| e.value.is_a?(String)}&lt;br /&gt;&lt;br /&gt;  # Does cache contain the ultimate question of life, the universe, and everything?&lt;br /&gt;  cache.any? {|e| e.name == &amp;#x27;The Ultimate Question&amp;#x27;}&lt;br /&gt;&lt;br /&gt;  # Sum of all numeric cache entries.&lt;br /&gt;  cache.inject(0) {|sum, e| e.value.is_a?(Numeric) ? sum + e.value : sum}&lt;br /&gt;&lt;br /&gt;  # Find the email address of creators of inferior programming languages&lt;br /&gt;  cache.reject {|e| e.value == &amp;#x27;Ruby&amp;#x27;}.map {|e| e.value.creator_email}.uniq&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;This is just a small preview of what Ruby's &lt;code&gt;Enumerable&lt;/code&gt; provides.  For full reference, see the &lt;a href="http://www.ruby-doc.org/core/classes/Enumerable.html"&gt;documentation on ruby-doc.org&lt;/a&gt;.  Be aware that if you have a large cache, this kind of iteration over every element could be prohibitively expensive, but for smaller caches it provides a very powerful querying mechanism.  For large caches, there is a new &lt;a href="http://ehcache.org/apidocs/net/sf/ehcache/search/package-summary.html"&gt;search API for Ehcache&lt;/a&gt; currently in the works, which uses indexing for efficient searching and will be available in an upcoming Ehcache release.&lt;/p&gt;&lt;!--&lt;p&gt;&lt;br /&gt;&lt;br /&gt;One final added feature is a &lt;code&gt;compare_and_swap&lt;/code&gt; method that allows you to atomically update the value of a cache element.  This method was added specifically for the Rails cache &lt;code&gt;increment&lt;/code&gt; and &lt;code&gt;decrement&lt;/code&gt; operations, but it is also available for your code to use directly.  It is most easily understood by example, so here is the unit test for the &lt;code&gt;compare_and_swap&lt;/code&gt; method:&lt;/p&gt;&lt;pre class="brush:ruby"&gt;must 'correctly implement compare and swap' do&lt;br /&gt;    @cache.put('number', 42, {:ttl =&gt; 120})&lt;br /&gt;    assert_equal(42, @cache['number'])&lt;br /&gt;    @cache.compare_and_swap('number') {|n| n - 31}&lt;br /&gt;    assert_equal(11, @cache['number'])&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;As you can see from the unit test, the &lt;code&gt;compare_and_swap&lt;/code&gt; method updates the value of the cache entry with the new value computed by the block, but what might not be obvious is that it does so atomically.  Underneath the covers, it uses a simple &lt;i&gt;spin-waiting&lt;/i&gt; loop combined with Ehcache's atomic &lt;code&gt;replace&lt;/code&gt; method to do its work.&lt;/p&gt;--&gt; &lt;p&gt;There are several other ways in which the Ruby API has been enhanced but I can't describe all of them here.  If you're curious, see the RDoc API documentation that is bundled with the jruby-ehcache gem.  And, of course, because the full Java API is available to you, you can also use the &lt;a href="http://ehcache.org/apidocs/index.html"&gt;Ehcache Javadocs&lt;/a&gt; for reference.&lt;/p&gt;&lt;h2&gt;Fewer Calories&lt;/h2&gt;&lt;p&gt;In addition to adding the above features, we've also done some fat trimming for this latest release.  First and foremost, we have deprecated the YAML configuration option in favor of using the Ehcache native XML configuration.  We know that some Rubyists will be disappointed by this decision ("What?  More XML?"), but we feel it was the right decision for several reasons:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The YAML configuration code is by far the most complicated bit of code in the Ehcache JRuby integration and we feel that it is a likely source of bugs.&lt;/li&gt;&lt;li&gt;YAML configuration is handled by pure Ruby code, and the Ehcache Java code is completely ignorant of it.  Any time that there is a change to the Ehcache configuration format, it would require an update and new release to the Ruby YAML code, meaning that we'd be playing a continual catch-up game with Ehcache core.&lt;/li&gt;&lt;li&gt;There are subtle differences between the YAML configuration and the XML configuration that we feel can only lead to confusion in the long run.&lt;/li&gt;&lt;li&gt;Java developers who already use Ehcache will already have ehcache.xml configuration files that they can now use directly instead of translating to YAML.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;While we're talking about configuration, I should mention that we've made some improvements to how your configuration files are located.  Previous versions of jruby-ehcache required that you place a config.yml file in your &lt;code&gt;$HOME/lib/config&lt;/code&gt; directory, which of course made it less than practical to have more than one application using jruby-ehcache at any given time.  With version 1.0.0 you have a lot more options available to you.  Now you can put your ehcache.xml either in the same directory as the Ruby file that creates the &lt;code&gt;CacheManager&lt;/code&gt; object, or place it in your Java &lt;code&gt;CLASSPATH&lt;/code&gt;, or you can specify any location in your call to the &lt;code&gt;CacheManager&lt;/code&gt; constructor.  If you are using Rails, then ehcache.xml will continue to reside in the canonical Rails &lt;code&gt;config&lt;/code&gt; directory.&lt;/p&gt;&lt;p&gt;Finally, we've removed a limitation that prevented you from using versions of Ehcache other than that bundled with the jruby-ehcache gem, and made it easy to drop in Enterprise Ehcache JARs into your application.  With the latest updates, jruby-ehcache will use your Java &lt;code&gt;CLASSPATH&lt;/code&gt; to locate the Ehcache JARs it should use, instead of forcing the use of the bundled Ehcache.  In my next blog post I will discuss how you can take advantage of this to add BigMemory to your application, or utilize distributed caching with Terracotta for linear scale out.&lt;/p&gt;&lt;h2&gt;Further Reading&lt;/h2&gt;&lt;p&gt;If you are interested in learning more about Ehcache and any of its associated add-ons, there are numerous resources available to you.  Here are a few to get you started. &lt;ul&gt;&lt;li&gt;The &lt;a href="http://www.ehcache.org/documentation/integrations/jruby"&gt;official Ehcache JRuby documentation&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The JRuby &lt;a href="http://kenai.com/projects/jruby/pages/CallingJavaFromJRuby"&gt;"Calling Java From Ruby" wiki page&lt;/a&gt; which describes the JRuby mechanisms for calling Java code from Ruby code, all of which applies to using Ehcache from JRuby.&lt;/li&gt;&lt;li&gt;The &lt;a href="http://ehcache.org/"&gt;Ehcache web site&lt;/a&gt;, which includes a &lt;a href="http://ehcache.org/documentation/"&gt;wealth of documentation&lt;/a&gt; and even a &lt;a href="http://ehcache.org/documentation/EhcacheUserGuide-1.7.1.pdf"&gt;complete book&lt;/a&gt; covering everything you could want to know about Ehcache.&lt;/li&gt;&lt;li&gt;The &lt;a href="http://www.terracotta.org/"&gt;Terracotta web site&lt;/a&gt; including information about &lt;a href="http://www.terracotta.org/ehcache/"&gt;Enterprise Ehcache&lt;/a&gt;, &lt;a href="http://www.terracotta.org/bigmemory"&gt;BigMemory&lt;/a&gt;and the &lt;a href="http://www.terracotta.org/snap-in"&gt;snap in, speed up, scale out&lt;/a&gt; approach to scaling applications.&lt;/li&gt;&lt;li&gt;The &lt;a href="https://github.com/dylanz/ehcache"&gt;GitHub project page&lt;/a&gt; for Ehcache JRuby integration.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;During my development on jruby-ehcache, I heavily utilized Gregory T. Brown's excellent book &lt;a href="http://www.amazon.com/gp/product/0596523009?ie=UTF8&amp;tag=wintermute&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596523009"&gt;Ruby Best Practices&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=wintermute&amp;l=as2&amp;o=1&amp;a=0596523009" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /&gt; for tips and techniques.  I highly recommend this book to anyone doing serious Ruby development. &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9099290662356800026-7012834099915148362?l=jvoegele.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvoegele.blogspot.com/feeds/7012834099915148362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jvoegele.blogspot.com/2010/11/ehcache-for-jruby-and-rails-now-with.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9099290662356800026/posts/default/7012834099915148362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9099290662356800026/posts/default/7012834099915148362'/><link rel='alternate' type='text/html' href='http://jvoegele.blogspot.com/2010/11/ehcache-for-jruby-and-rails-now-with.html' title='Ehcache for JRuby and Rails: Now with more flavor and fewer calories'/><author><name>Jason Voegele</name><uri>http://www.blogger.com/profile/16938133385202930039</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://4.bp.blogspot.com/_XMi6F4SX8RQ/TLxSUt_z7DI/AAAAAAAAABk/BlQUMHop_Ys/S220/jason.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9099290662356800026.post-1730701875265802750</id><published>2010-10-23T11:41:00.000-07:00</published><updated>2010-10-23T11:41:58.959-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='how-to'/><category scheme='http://www.blogger.com/atom/ns#' term='samsung epic'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>How to Improve Battery Life for the Samsung Epic 4G</title><content type='html'>&lt;a href="http://www.amazon.com/gp/product/B003ZDO2H6?ie=UTF8&amp;amp;tag=wintermute&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=B003ZDO2H6"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_XMi6F4SX8RQ/TMMsH6_cwUI/AAAAAAAAACM/AM6JtpzeFdA/s1600/51gzGHFZvIL._SL160_.jpg" style="float: left; margin-bottom: 1em; margin-left: 1em; margin-right: 1em; margin-top: 1em;" /&gt;&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=wintermute&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=B003ZDO2H6" style="border: none !important; margin: 0px !important;" width="1" /&gt;&lt;br /&gt;I recently purchased a new Android phone, the Samsung Epic 4G from Sprint, and I love almost everything about it.  However, when I first started using the phone battery life was absolutely horrendous.  Even with light usage I was unable to make it through a full day on a single charge and I often had to plug the phone in and charge it several times per day.  Now, though, I've done some research and experimentation and am happy to report that not only does my phone make it through the whole day on a single charge, but I also have upwards of 40% battery remaining when I go to bed at night.  Now I can let the kids play Angry Birds without fear of my phone dying.&lt;br /&gt;This post will explain how you too can achieve good battery life for your Samsung Epic or other Android phone, and do so without sacrificing the functionality you've come to depend on.  (Note: while much of the advice in this blog post is specific to the Samsung Epic, there are some general strategies that apply to any Android phone, so you may find something of interest even if you do not own an Epic.)&lt;br /&gt;&lt;h2&gt;A Note About Task Killers and Other Ineffective Practices&lt;/h2&gt;If you read a typical forum post from a poor user suffering from battery life problems, the post will usually start out with frustrated pleadings like&lt;br /&gt;&lt;blockquote&gt;I've tried everything!  I turn off Wi-Fi, live wallpaper, and use Advanced Task Killer to kill all running apps and services, but nothing works!  Help!&lt;/blockquote&gt;Usually the helpful people trying to answer such pleadings offer further advice about turning off GPS and Bluetooth, or reducing screen brightness and timeout.  While these techniques can provide incremental improvements to battery life, they do so at the cost of functionality of your phone.  I do personally keep Bluetooth disabled when I'm not using it, but always leave wifi and GPS enabled (GPS does not consume any power just by being enabled, only when an app is actively using it).  And of course, 4G data connections are known to be a serious battery hog so you probably don't want to leave that on all the time.&lt;br /&gt;Automatic task killers, though, are most likely doing more harm than good and I do not recommend using them.  Android manages tasks and processes quite well on its own and automatic task killers interfere with Android's normal mode of operation.  Any time a process is killed, it means that it will consume &lt;em&gt;more&lt;/em&gt; power next time it needs to be started.  Furthermore, many of the tasks that are killed by these auto task killers are important components of your phone's functionality and having them killed in the background is only crippling your phone.  I do keep a task killer app on my phone, but only use it when I suspect that an application is misbehaving, and can then individually kill the suspect app.  Never let an automatic task killer indiscriminately kill apps or services in the background; doing so is just shooting yourself in the foot.&lt;br /&gt;With that little lecture out of the way, let's look at some practices that are effective at enhancing battery life.&lt;br /&gt;&lt;h2&gt;Disable the DRM Service&lt;/h2&gt;The Samsung Epic (and presumably other Samsung Galaxy S class phones) come with the Media Hub application for viewing movies and television programs.  While this may some day address a gap in the Android platform, as it stands today the Media Hub application offers only a very limited set of programs for rent or purchase.  Worse yet, though, the DRM service that comes with the application is a severe power hog.  The biggest battery boosting technique you can perform for the Epic is to disable this service altogether.&lt;br /&gt;To disable the DRM service, start from your Android home screen and then go to:&lt;br /&gt;&lt;div class="code"&gt;&lt;code&gt;Menu → Settings → Applications → Running services&lt;/code&gt;&lt;/div&gt;Once there you should see an entry for the Samsung DRM service.  Click on this entry to disable the service, and voilà, you instantly have better battery life.&lt;br /&gt;&lt;div class="note"&gt;(Note: while you are there, take a look around and see if there are other services running that you do not need.  I disabled a couple of other services on my phone, namely the Aloqa widget update service, and the SportsTap widget service since I don't use either of these widgets.)&lt;/div&gt;You may come to find that this service spontaneously springs back to life.  You could occasionally repeat this process and stop the service whenever you notice it is running, but why would you want to do that when your phone can do it for you?  To permanently kill this service you can use a startup auditing application to make sure that it doesn't reincarnate.  I installed the &lt;a href="http://www.androlib.com/android.application.com-vesperanovus-app-startupauditor-qDxn.aspx"&gt;Startup Auditor&lt;/a&gt; app, which is a paid application but there are free apps that offer similar functionality.  With Startup Auditor I was able make sure that the DRM service did not start automatically at boot time, and furthermore would never spontaneously start itself at all.&lt;br /&gt;&lt;table border="1" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;&lt;img src="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=135x135&amp;amp;chl=market%3a%2f%2fdetails%3fid%3dcom.vesperaNovus.app.StartupAuditorFree%26referrer%3dutm_source%253DAndrolib%2526utm_medium%253DPage%2526utm_campaign%253DAndrolib%2520Page" /&gt;&lt;/td&gt;     &lt;td&gt;&lt;a href="http://www.androlib.com/android.application.com-vesperanovus-app-startupauditorfree-jzjiw.aspx"&gt;Startup Auditor Free&lt;/a&gt;&lt;br /&gt;A boot monitor and startup monitor tool which displays a list of applications you may disable.  Free version supported by ads.&lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;     &lt;td&gt;&lt;img height="135" src="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=135x135&amp;amp;chl=market%3a%2f%2fdetails%3fid%3dcom.vesperaNovus.app.StartupAuditor%26referrer%3dutm_source%253DAndrolib%2526utm_medium%253DPage%2526utm_campaign%253DAndrolib%2520Page" width="135" /&gt;&lt;/td&gt;     &lt;td&gt;&lt;a href="http://www.androlib.com/android.application.com-vesperanovus-app-startupauditor-qDxn.aspx"&gt;Startup Auditor&lt;/a&gt;&lt;br /&gt;A boot monitor and startup monitor tool which displays a list of applications you may disable.  Full version eliminates ads and can disable unlimited.&lt;/td&gt;   &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Note that the Media Hub application probably will not function if you've disabled the DRM service.  I do not personally use this app so this is no loss for me.&lt;br /&gt;&lt;h2&gt;The Airplane Mode Toggle Trick&lt;/h2&gt;One of the biggest drains on a mobile phone battery is when there is a weak signal and the cellular radio frequently scans for a signal.  Not much can be done about this when reception truly is weak or there is no signal whatsoever.  However, there is an insidious bug in the current Epic firmware that "tricks" the phone into thinking it does not have a signal, and causing the power drain while the phone is scanning for a good signal&amp;amp;emdash;even though it already has one!&lt;br /&gt;You can tell if you are affected by this bug by checking your battery usage:&lt;br /&gt;&lt;div class="code"&gt;(Menu) → Settings → About phone → Battery use → Cell standby&lt;/div&gt;On this screen you will see a line that reads "Time without a signal".  If you've been in a good coverage area but the percentage on this line is high (say 50% or so) then you are suffering from the bug described previously.&lt;br /&gt;Now, how to fix it?  Until Samsung or Sprint provides us with an update, there is a simple trick that works around this bug.  All you have to do is put your phone in airplane mode.  Hold down the power button on your phone until the pop-up menu appears and then select &lt;em&gt;Airplane mode&lt;/em&gt;.  Wait approximately 15 seconds, then repeat the process to take your phone back out of airplane mode.  For reasons that are not clear to anyone, this airplane mode toggle will prevent the false weak signal bug and the battery drain that goes along with it.&lt;br /&gt;One important thing to note is that this workaround does not survive a power cycle.  You will need to repeat this process every time you restart your phone.&lt;br /&gt;&lt;h2&gt;Prevent Wi-Fi Sleep&lt;/h2&gt;An oft-cited bit of advice is to disable wi-fi to preserve battery power.  While this may be true for who are not frequently connected to wi-fi or who spend most of their time on the road, it is actually counter productive if you are usually within range of a wi-fi access point.  This is because an active 3G connection consumes more power than an active wi-fi connection.  To make matters worse, though, Android's default settings for wi-fi sleep policy are suboptimal.  The default setting is to disconnect from wi-fi whenever the screen timeout has been reached, and this in turn causes a 3G data connection to activate.  When you turn your phone screen back on your phone will then reconnect to wi-fi.  This cycle of wi-fi off → 3G on → 3G off → wi-fi on consumes significant amounts of power.  It would be better to leave the wi-fi connection active regardless of the state of the screen.  You can do this by changing the wi-fi sleep policy:&lt;br /&gt;&lt;code&gt;(Menu) → Settings → Wireless &amp;amp; networks → Wi-Fi settings → (Menu) → Advanced → Wi-Fi sleep policy &lt;/code&gt;&lt;br /&gt;Change the setting to &lt;b&gt;Never&lt;/b&gt;.  I work from home and am therefore usually in range of my wireless router.  I speak from experience when I say that this change can make a significant difference in battery life.&lt;br /&gt;What about the road warriors among you, though?  If you are typically out and about and not always connected to a wi-fi access point, changing the global Wi-Fi sleep policy will probably prove detrimental, as your phone will constantly keep scanning for wi-fi connections even when it is otherwise sleeping.  Fear not, there is a solution for you too, at least if you don't mind paying for the overall excellent &lt;i&gt;Locale&lt;/i&gt; app and installing a couple of very useful plugins.  Here is what you will need:&lt;br /&gt;&lt;table border="1px" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;     &lt;td&gt;&lt;img src="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=135x135&amp;amp;chl=market%3a%2f%2fdetails%3fid%3dcom.twofortyfouram.locale%26referrer%3dutm_source%253DAndrolib%2526utm_medium%253DPage%2526utm_campaign%253DAndrolib%2520Page" /&gt;&lt;/td&gt;     &lt;td&gt;&lt;a href="http://www.androlib.com/android.application.com-twofortyfouram-locale-pzmC.aspx"&gt;&lt;i&gt;Locale&lt;/i&gt;&lt;/a&gt;&lt;br /&gt;A powerful app allowing you to create situations and apply settings and other actions when the situation is active&lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;     &lt;td&gt;&lt;img src="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=135x135&amp;amp;chl=market%3a%2f%2fdetails%3fid%3dat.abraxas.keepwifi.locale%26referrer%3dutm_source%253DAndrolib%2526utm_medium%253DPage%2526utm_campaign%253DAndrolib%2520Page" /&gt;&lt;/td&gt;     &lt;td&gt;&lt;a href="http://www.androlib.com/android.application.at-abraxas-keepwifi-locale-qtx.aspx"&gt;KeepWiFi Locale&lt;/a&gt;&lt;br /&gt;A &lt;i&gt;Locale&lt;/i&gt; plugin that keeps wi-fi enabled when active&lt;/td&gt;   &lt;/tr&gt;&lt;tr&gt;     &lt;td&gt;&lt;img src="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=135x135&amp;amp;chl=market%3a%2f%2fdetails%3fid%3dnet.andvari.android.wificonnection%26referrer%3dutm_source%253DAndrolib%2526utm_medium%253DPage%2526utm_campaign%253DAndrolib%2520Page" /&gt;&lt;/td&gt;     &lt;td&gt;&lt;a href="http://www.androlib.com/android.application.net-andvari-android-wificonnection-DmFw.aspx"&gt;Locale Wifi Connection Plugin&lt;/a&gt;&lt;br /&gt;A &lt;i&gt;Locale&lt;/i&gt; Plug-in that allows you to set a condition based on what wifi network you're connected to, instead of within range of&lt;/td&gt;   &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;With these tools in hand, here is how you can construct a &lt;i&gt;Locale&lt;/i&gt; situation that keeps wi-fi enabled when you are connected to a preferred network, but then reverts to the default Android sleep policy when not connected to this network.  (First, if you have already followed the above steps to set your sleep policy to &lt;em&gt;Never&lt;/em&gt;, you should now set it back to the default value of &lt;em&gt;When screen turns off&lt;/em&gt;.)&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open &lt;i&gt;Locale&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Create a &lt;em&gt;Defaults&lt;/em&gt; situation if you do not already have one.&lt;/li&gt;&lt;li&gt;Go into the &lt;em&gt;Defaults&lt;/em&gt; situation.&lt;/li&gt;&lt;li&gt;Push &lt;em&gt;Add Setting&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Push &lt;em&gt;Keep WiFi&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Leave the value for &lt;em&gt;KeepWiFi Service&lt;/em&gt; as &lt;em&gt;Off&lt;/em&gt;, then use the back button on your phone to go back.&lt;/li&gt;&lt;li&gt;Save the &lt;em&gt;Defaults&lt;/em&gt; situation (Menu → Save).&lt;/li&gt;&lt;li&gt;Push &lt;em&gt;Add Situation&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Enter a name for the situation (I named mine after my home wi-fi network).&lt;/li&gt;&lt;li&gt;Push &lt;em&gt;Add Condition&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Choose &lt;em&gt;Wifi Connection&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Enter the SSID of your wi-fi network, the use the back button on your phone to go back.&lt;/li&gt;&lt;li&gt;Push &lt;em&gt;Add Setting&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;Choose &lt;em&gt;Keep WiFi&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;This time change the &lt;em&gt;KeepWiFi Service&lt;/em&gt; value to &lt;em&gt;On&lt;/em&gt;, then use the back button on your phone to go back.&lt;/li&gt;&lt;li&gt;Finally, save the new situation (Menu → Save).&lt;/li&gt;&lt;/ol&gt;Now whenever you are connected to your preferred wi-fi network, the wi-fi connection will be kept active, preserving power by not switching to 3G data connection.  When you are not connected to this network the default wi-fi sleep policy will be used, preserving power by not constantly scanning for wi-fi networks even when the phone screen is off.  &lt;i&gt;Locale&lt;/i&gt; allows you to have the best of both worlds.&lt;br /&gt;&lt;h2&gt;Other Miscellaneous Tips&lt;/h2&gt;The following are more well-known tips for extending battery life and since most people are probably already aware of them I don't feel I need to expound upon them very much, but I include them here for reference.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Disable 4G data connections whenever not actually in use.&lt;/li&gt;&lt;li&gt;Uninstall any apps that you do not use and do not plan to use.&lt;/li&gt;&lt;li&gt;Limit the frequency of background sync for things like Facebook, Twitter, email, etc.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9099290662356800026-1730701875265802750?l=jvoegele.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvoegele.blogspot.com/feeds/1730701875265802750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jvoegele.blogspot.com/2010/10/how-to-improve-battery-life-for-samsung.html#comment-form' title='34 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9099290662356800026/posts/default/1730701875265802750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9099290662356800026/posts/default/1730701875265802750'/><link rel='alternate' type='text/html' href='http://jvoegele.blogspot.com/2010/10/how-to-improve-battery-life-for-samsung.html' title='How to Improve Battery Life for the Samsung Epic 4G'/><author><name>Jason Voegele</name><uri>http://www.blogger.com/profile/16938133385202930039</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://4.bp.blogspot.com/_XMi6F4SX8RQ/TLxSUt_z7DI/AAAAAAAAABk/BlQUMHop_Ys/S220/jason.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_XMi6F4SX8RQ/TMMsH6_cwUI/AAAAAAAAACM/AM6JtpzeFdA/s72-c/51gzGHFZvIL._SL160_.jpg' height='72' width='72'/><thr:total>34</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9099290662356800026.post-2582459268213208912</id><published>2010-10-21T13:03:00.000-07:00</published><updated>2010-12-07T08:17:13.616-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='jruby'/><category scheme='http://www.blogger.com/atom/ns#' term='terracotta'/><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='scalability'/><category scheme='http://www.blogger.com/atom/ns#' term='ehcache'/><title type='text'>Terabyte Scale for JRuby and Rails</title><content type='html'>&lt;p&gt;In this, my inaugural blog post, I'm going to explain how you can use Ehcache and Terracotta from your JRuby and Rails applications.  &lt;a href="http://www.ehcache.org/"&gt;Ehcache&lt;/a&gt; is the most popular open source caching solution in the Java landscape and &lt;a href="http://www.terracotta.org/ehcache/"&gt;Terracotta's Enterprise Ehcache&lt;/a&gt; provides the ultimate in scalability allowing you to store over a terabyte of data in a fully coherent cache.  And now you can use it to provide unprecedented levels of scale to the Rails world.&lt;/p&gt;&lt;h2&gt;A Little Bit of History&lt;/h2&gt;&lt;p&gt;I work at &lt;a href="http://www.terracotta.org/"&gt;Terracotta&lt;/a&gt; and one of the fun things we do there is to have a semi-annual "dev week", during which the whole distributed team gathers together in our San Francisco office to collaborate in person.  During our last dev week we had a product improvement competition and my entry into the competition was a set of Ruby Gems to provide integration between Ehcache and JRuby/Rails.  To do this, I built on top of the &lt;a href="http://github.com/dylanz/ehcache"&gt;work done by Dylan Stamat&lt;/a&gt;, who originally created the JRuby Ehcache integration.  As with so many other open-source projects maintained by people in their free time, this project had been lying dormant for some time while Dylan was busy with other obligations.  I decided to pick up where Dylan left off and as a result of this there is a new set of Ruby Gems for working with Ehcache from JRuby, Rails 2, and Rails 3.&lt;/p&gt;&lt;p&gt;Caching in Rails has traditionally been done using memcached, either directly using the Memcache API or using the Rails caching API with a memcached backend.  While this has worked fairly well for most people, there are some limitations to memcached that have led some to seek alternative solutions.  If you limit yourself to solutions that work with the standard C implementation of Ruby ("Matz's Ruby Implementation") then memcached is likely your best bet.  However, if you are able to use JRuby, a whole new universe of caching solutions emerges, now including the very popular Ehcache.&lt;/p&gt;&lt;h2&gt;Using Ehcache with JRuby&lt;/h2&gt;&lt;p&gt;Ehcache JRuby integration is provided by the jruby-ehcache gem.  To install it simply execute:&lt;/p&gt;&lt;pre class="brush: plain"&gt;jgem install jruby-ehcache&lt;/pre&gt;&lt;p&gt;&lt;strike&gt;Ehcache configuration is done with the ehcache.yml YAML file.  The jruby-ehcache gem includes a default ehcache.yml file, but if you would like to customize it you can copy the ehcache.yml file bundled with the gem and place it in your $HOME/lib/config directory and then edit it as you see fit.&lt;/strike&gt; (This is no longer true.  See my blog post &lt;a href="http://jvoegele.blogspot.com/2010/11/ehcache-for-jruby-and-rails-now-with.html"&gt;Ehcache for JRuby and Rails: Now with more flavor and fewer calories&lt;/a&gt; for information about recent changes.)&lt;/p&gt;&lt;p&gt;Now it is time to start using Ehcache.  Let's take a look at a simple example that uses the Ehcache::CacheManager to create a cache, and then puts and gets some date in the cache.&lt;/p&gt;&lt;pre class="brush: ruby"&gt;require 'ehcache'&lt;br /&gt;&lt;br /&gt;manager = Ehcache::CacheManager.new&lt;br /&gt;cache = manager.cache&lt;br /&gt;&lt;br /&gt;cache.put("answer", "42", {:ttl =&amp;gt; 120})&lt;br /&gt;answer = cache.get("answer")&lt;br /&gt;puts "Answer: #{answer}"&lt;br /&gt;question = cache.get("question") || 'unknown'&lt;br /&gt;puts "Question: #{question}"&lt;br /&gt;&lt;br /&gt;manager.shutdown&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Save this code as "jruby-ehcache-demo.rb" and execute it as follows:&lt;/p&gt;&lt;pre class="brush:bash"&gt;jruby -rubygems jruby-ehcache-demo.rb&lt;/pre&gt;&lt;p&gt;As you can see from the example, you create a cache using CacheManager.new, and you can control the "time to live" value of a cache entry using the :ttl option in cache.put.  Note that not all of the Ehcache API is currently exposed in the JRuby API, but most of what you need is available and we plan to add a more complete API wrapper in the future.&lt;/p&gt;&lt;h2&gt;Using Ehcache in Rails Applications&lt;/h2&gt;&lt;p&gt;To use Ehcache from a Rails application you must first install the correct gem for your Rails version.&lt;/p&gt;&lt;pre class="brush: plain"&gt;jgem install jruby-ehcache-rails2 # for Rails 2&lt;br /&gt;jgem install jruby-ehcache-rails3 # for Rails 3&lt;/pre&gt;&lt;p&gt;Configuration of Ehcache is still done with the ehcache.yml file, but for Rails applications you must place this file in the config directory of your Rails app.  Note that you must use JRuby to execute your Rails application, as these gems utilize JRuby's Java integration to call the Ehcache API.&lt;/p&gt;&lt;p&gt;With this configuration out of the way, you can now use the Ehcache API directly from your Rails controllers and/or models.  You could of course create a new Cache object everywhere you want to use it, but it is better to create a single instance and make it globally accessible by creating the Cache object in your Rails environment.rb file.  For example, you could add the following lines to config/environment.rb:&lt;/p&gt;&lt;pre class="brush: ruby"&gt;require 'ehcache'&lt;br /&gt;EHCACHE = Ehcache::CacheManager.new.cache&lt;/pre&gt;&lt;p&gt;By doing so, you make the EHCACHE constant available to all Rails-managed objects in your application.  Using the Ehcache API is now just like the above JRuby example.&lt;/p&gt;&lt;p&gt;If you are using Rails 3 then you have a better option at your disposal: the built-in Rails 3 caching API.  This API provides an abstraction layer for caching underneath which you can plug in any one of a number of caching providers.  ﻿The most common provider to date has been the memcached provider, but now you can also use the Ehcache provider.  Switching to the Ehcache provider requires only one line of code in your Rails environment file:&lt;/p&gt;&lt;pre class="brush: ruby"&gt;config.cache_store = :ehcache_store&lt;/pre&gt;&lt;p&gt;A very simple example of the Rails caching API is as follows:&lt;/p&gt;&lt;pre class="brush: ruby"&gt;Rails.cache.write("answer", "42")&lt;br /&gt;Rails.cache.read("answer")  # =&gt; '42'&lt;/pre&gt;&lt;p&gt;Using this API, your code can be agnostic about the underlying provider, or even switch providers based on the current environment (e.g. memcached in development mode, Ehcache in production).&lt;/p&gt;&lt;p&gt;If you'd like to see a complete example of an Ehcache-enabled Rails application, check out this demo that I wrote to show Ehcache in action:&lt;/p&gt;&lt;p&gt;&lt;a href="http://svn.terracotta.org/svn/forge/projects/ehcache-rails-demo/trunk"&gt;http://svn.terracotta.org/svn/forge/projects/ehcache-rails-demo/trunk&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;With Ehcache plugged into your Rails application you have a whole slew of options to address all of those Enterprisey concerns.  With Terracotta's Enterprise Ehcache product you can have the ultimate in scalability by taking advantage of &lt;a href="http://ehcache.org/documentation/distributed_caching.html"&gt;distributed caching&lt;/a&gt; or eliminating Java garbage collection pauses with &lt;a href="http://ehcache.org/documentation/offheap_store.html"&gt;BigMemory&lt;/a&gt;.  Plug in a &lt;a href="http://www.terracotta.org/documentation/3.1.x/product-documentation-15.html"&gt;Terracotta Server Array&lt;/a&gt; behind your clustered Rails application and you can store hundreds of millions of keys in your cache, and over a terabyte of data.&lt;/p&gt;&lt;p&gt;If you'd like to use Rails for your web app but your boss has concerns about scalability, Ehcache might just be for you.&lt;/p&gt;&lt;p&gt;You can read further documentation on the &lt;a href="http://ehcache.org/documentation/jruby.html"&gt;Ehcache web site&lt;/a&gt;, or grab the source from &lt;a href="http://github.com/dylanz/ehcache"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/9099290662356800026-2582459268213208912?l=jvoegele.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jvoegele.blogspot.com/feeds/2582459268213208912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jvoegele.blogspot.com/2010/10/terabyte-scale-for-jruby-and-rails.html#comment-form' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9099290662356800026/posts/default/2582459268213208912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9099290662356800026/posts/default/2582459268213208912'/><link rel='alternate' type='text/html' href='http://jvoegele.blogspot.com/2010/10/terabyte-scale-for-jruby-and-rails.html' title='Terabyte Scale for JRuby and Rails'/><author><name>Jason Voegele</name><uri>http://www.blogger.com/profile/16938133385202930039</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='30' src='http://4.bp.blogspot.com/_XMi6F4SX8RQ/TLxSUt_z7DI/AAAAAAAAABk/BlQUMHop_Ys/S220/jason.jpg'/></author><thr:total>6</thr:total></entry></feed>
