Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

A friend in need - A JS indeed

797 views

Published on

Talk about how to outsource business logic to the server, use V8 engine to execute JS without compromising performance and have fun.

Published in: Software
  • Be the first to comment

A friend in need - A JS indeed

  1. 1. A friend in need - a JS indeed +
  2. 2. Yonatan Levin levin.yonatan parahall Gett Google Developer Expert
  3. 3. 70 Cities > 20M usersRuby, Go, Python, Microservices
  4. 4. ~ 2000 members Largest Android Active Community
  5. 5. What Do We Do? ● Android Fundamentals ● Android UI / UX ● Community Hackathon ● Android Performance ● Mentors Program ● Active community
  6. 6. What we are going to do? Fun! GetTaxi Gett story V8 engine Dynamic UI Concept
  7. 7. Let’s make it even more engaging
  8. 8. Count how many times word Gett appears in the presentation
  9. 9. Let the fun begin!
  10. 10. Imagine...
  11. 11. Slide about Gett
  12. 12. Intro - Normal World Customer App iOS / Android Server Supplier App iOS / Android
  13. 13. Offline/2G
  14. 14. Our World Server Customer App iOS / Android Supplier App iOS / Android
  15. 15. Ability to calculate price without server instantly
  16. 16. First approach Server Pricing Calculator Pricing Calculator Supplier App iOS / Android
  17. 17. Same logic - 4 times Server Pricing Calculator Pricing Calculator Pricing Calculator Pricing Calculator
  18. 18. Product guy: - We need an ability to create a new class every day. - Every single moment!
  19. 19. Pain of Upgrade
  20. 20. “Fool me once, shame on you; fool me twice, shame on me.” Italian proverb
  21. 21. Server creates Pricing Calculator Pricing Calculator Gem JS Code Ruby Code
  22. 22. Runtime Flow App Server Container (Rails) Pricing Calculator Gem JS Code Ruby Code Load JS Pricing Calculator Server-side Calculation API Supplier App iOS / Android JS Runtime JS Pricing Calculator
  23. 23. Different Capabilities of Execution Context Pricing Calculator (Ruby) Server Network CallNetwork Call Supplier App iOS / Android JS Runtime JS Pricing Calculator
  24. 24. Architecture is ready. What next?
  25. 25. WebView
  26. 26. JavaScript final String javaScriptCode = "var recursive = function(n) {" + " if(n <= 2) {" + " return 1;" + " } else {" + " return this.recursive(n - 1) + this.recursive(n - 2);" + " }" + "};" + "recursive(28)"; mWebView = (WebView) findViewById(R.id.webview); WebSettings webSettings = mWebView.getSettings(); webSettings.setJavaScriptEnabled(true); mWebView.evaluateJavascript(javaScriptCode, this);
  27. 27. Average Top Device: ~42 ms Average Low End Device: ~92 ms
  28. 28. WebView Various version Depends on what is installed on device Not controllable We have a lot of “Made in China” devices
  29. 29. We love native-development
  30. 30. V8
  31. 31. V8 V8 is Google's open source high-performance JavaScript engine, written in C++ and used in Google Chrome And also Node.JS https://developers.google.com/v8/
  32. 32. You can use it native https://github.com/v8/v8/wiki/D8%20on%20Android
  33. 33. Write some JNI code V8Runner::V8Runner () { isolate = Isolate::New(); Locker l(isolate); Isolate::Scope isolateScope(isolate); HandleScope handle_scope; context = Persistent<Context>(Context::New()); } void V8Runner::mapMethod (JNIEnv* env, jobject v8MappableMethod, const char* name) { Locker l(isolate); Isolate::Scope isolateScope(isolate); HandleScope handle_scope; Context::Scope context_scope(context); MappableMethodData* data = new MappableMethodData(); data->methodObject = env->NewGlobalRef(v8MappableMethod); env->GetJavaVM(&data->jvm); methodDatas.push_back(data); //context->DetachGlobal(); Handle<Object> global = context->Global(); global->Set(String::New(name), FunctionTemplate::New(&registerCallback, External::New(data))->GetFunction()); //context->ReattachGlobal(global); }
  34. 34. Eclipse J2V8 Small tiny library Wrapper for JNI Really easy to integrate and use
  35. 35. How to? compile 'com.eclipsesource.j2v8:j2v8:3.1.6@aar' mRuntime = V8.createV8Runtime(); int value = mRuntime.executeIntegerScript(javaScriptCode); mRuntime.executeStringScript(javaScriptCode); mRuntime.executeObjectScript(javaScriptCode);
  36. 36. ~23 ms
  37. 37. Back to Gett story
  38. 38. Download calculator on login Server Pricing CalculatorPricing Calculator
  39. 39. public VoidResponse downloadChargingEngine(String fileName, String filePath) { retrofit2.Call<ResponseBody> call = mGTServiceApi .downloadChargingEngine(ChargingEngine.VERSION); return getToFile(call, fileName, filePath, VoidResponse.class); }
  40. 40. JavascriptMeterComponent J2V8JavascriptEngine Warm your engines J2V8 Pricing Calculator
  41. 41. Start your engines protected static JavascriptMeterComponent createJavaScriptComponent(String javascriptFilePath) { J2V8JavascriptEngine javascriptEngine = new J2V8JavascriptEngine(); JavascriptMeterComponent javascriptMeterComponent = new JavascriptMeterComponent(javascriptEngine); File file = new File(javascriptFilePath,J2V8JavascriptEngine.J2V8JavascriptFileName); javascriptMeterComponent .loadChargingEngine(new java.io.FileInputStream(file)); return javascriptMeterComponent; }
  42. 42. JavascriptMeterComponent J2V8JavascriptEngine Run!!!! J2V8 “calculate_and_adapt” Ride data Price (JSON)
  43. 43. Calculate public CalculationResult calculateAndAdaptOrderCost(Data data, String priceModel, String areasFixedPrice) { String rideData = mGson.toJson(data); String calculationAsJson = mJavascriptEngine .executeMethodOnObject("$calculate_and_adapt",rideData); return mGson.fromJson(calculationAsJson, CalculationResult.class); }
  44. 44. Wait, but where is the magic?
  45. 45. Taxi Cleaner iMaster
  46. 46. “adapt” that turns the raw data to UI key-value public class CalculationResult { private List<List<BreakdownRow>> breakdown; private Totals totals; }
  47. 47. “adapt” that turns the raw data to UI key-value public class BreakdownRow { String label; String value; @SerializedName("valueIsMonetary") boolean valueIsMonetary; String description; }
  48. 48. Flat and insert to list private void convertRowsToItems(List<List<OrderBreakdown.BreakdownRow>> breakdown) { List<RowItem> rowsItemsList = new ArrayList<>(); // flat the rows - show all row as an item for (List<OrderBreakdown.BreakdownRow> breakDownRowArray : breakdown) { for (OrderBreakdown.BreakdownRow breakdownRow : breakDownRowArray) { String description = breakdownRow.getDescription(); String RowLabel = breakdownRow.getLabel(); rowsItemsList.add(new RowItem(RowLabel, breakdownRow.getValue(), breakdownRow.isSummary(), breakdownRow.isValueIsMonetary())); } }
  49. 49. Taxi Cleaner iMaster
  50. 50. So what we had V8 Engine Business pricing logic outsourced to the server UI is no longer tightly coupled to the fields but built dynamically #PerfMatters
  51. 51. Launched Jul 2015 Moscow, Marathon of 4 dev days launching.
  52. 52. 2 AM Proguard cut our JNI Java Side :)
  53. 53. Return Val; Almost 1.5 year in production. 0 performance issues.
  54. 54. Server Pricing CalculatorPricing Calculator Download calculator from server
  55. 55. “It’s not us, it’s server”
  56. 56. Q?
  57. 57. What about Quizz?
  58. 58. parahall

×