René's URL Explorer Experiment


Title: Dasherize, Turbolinks 3 and Parallel · Issue #5 · jollygoodcode/jollygoodcode.github.io · GitHub

Open Graph Title: Dasherize, Turbolinks 3 and Parallel · Issue #5 · jollygoodcode/jollygoodcode.github.io

X Title: Dasherize, Turbolinks 3 and Parallel · Issue #5 · jollygoodcode/jollygoodcode.github.io

Description: We open-sourced Dasherize a few days ago. Dasherize is a simple, material-designed dashboard for your projects on which you can see: CI status of master branch (supports Travis CI, Codeship and CircleCI) GitHub Pull Requests and Issues c...

Open Graph Description: We open-sourced Dasherize a few days ago. Dasherize is a simple, material-designed dashboard for your projects on which you can see: CI status of master branch (supports Travis CI, Codeship and Cir...

X Description: We open-sourced Dasherize a few days ago. Dasherize is a simple, material-designed dashboard for your projects on which you can see: CI status of master branch (supports Travis CI, Codeship and Cir...

Opengraph URL: https://github.com/jollygoodcode/jollygoodcode.github.io/issues/5

X: @github

direct link

Domain: github.com


Hey, it has json ld scripts:
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Dasherize, Turbolinks 3 and Parallel","articleBody":"We open-sourced [Dasherize](http://github.com/jollygoodcode/dasherize) a few days ago.\n\n\u003ca href=\"http://www.dasherize.com\" target=\"_blank\"\u003e\u003cimg width=\"774\" alt=\"screenshot 2015-10-08 18 48 13\" src=\"https://cloud.githubusercontent.com/assets/1000669/10364359/280e45b0-6ded-11e5-96c3-4182d443a27e.png\"\u003e\u003c/a\u003e\n\nDasherize is a simple, material-designed dashboard for your projects on which you can see:\n- CI status of `master` branch (supports Travis CI, Codeship and CircleCI)\n- GitHub Pull Requests and Issues count and a peek of most recents\n\nMore importantly, Dasherize also has a presentation mode for big screen displays.\n\nThe [README](https://github.com/jollygoodcode/dasherize#origin) has more details of how Dasherize came about, so you can read that. \n\nThis blog post dives more into the technical details. \n## Turbolinks 3\n\nDasherize 3 uses [Turbolinks 3](https://github.com/rails/turbolinks) :tophat:. In fact, it's tracking `master` of Turbolinks now.\n\nSpecifically, it uses the [Partial Replacement](https://github.com/rails/turbolinks#partial-replacement-30) :sparkles:  technique that's only available in Turbolinks 3.\n### Which Feature?\n\nTurbolinks is used to load each \"Card\" on the dashboard.\n\n![1](https://cloud.githubusercontent.com/assets/2112/10364137/8a0ebf1c-6deb-11e5-9470-7aa9240cdd83.gif)\n### Code Walk Through\n\nWhen the dashboard loads, it first fills the dashboard with empty \"Cards\" (name only) for each project.\n\nThe code can be found in `app/views/projects/index.html.slim`, and the loop is:\n\n``` slim\n- if @projects.present?\n  .row.mar-lg-top\n    - @projects.each do |project|\n      .col.s12.m4\n        .project id=\"project:#{project.id}\"\n          = link_to project_path(project), project_path(project), remote: true, class: 'hide js-project'\n\n          .card-panel.no-padding.grey.darken-1\n            .card-heading\n              .card-title\n                = link_to project.repo_name\n                .right\n                  = link_to icon(\"gear\"), edit_project_path(project), class: \"gear\"\n            .card-status.center.progress\n              .indeterminate\n```\n\nThe important bit are the two lines below, while the rest are just markup that creates an empty \"Card\" with a progress bar.\n\n``` slim\n.project id=\"project:#{project.id}\"\n  = link_to project_path(project), project_path(project), remote: true, class: 'hide js-project'\n```\n\nThe `id` is important because this is the `id` to be used for Turbolinks Partial Replacement, so that a specific `.project` can be swapped out with a server response.\n\nNext, the anchor tag links to the `project_path(project)` which is a RESTful path to `projects#show` that shows (the \"Card\" for) one project.\n\nThe magic happens with `remote: true` and some JavaScript. When the page loads, JavaScript will trigger a click on all the anchor tags with `.js-project` class.\n\n``` javascript\n// app/assets/javascripts/projects.js\n\n$(\".js-project\").not('.in-progress').addClass('in-progress').click();\n```\n\nAs each link has `remote: true`, each click results in an async call to `projects#show` which looks like:\n\n``` ruby\n# app/controllers/projects_controller.rb\n\ndef show\n  @project = ProjectDecorator.new(@project)\n  @project.process_with(current_user.oauth_account.oauth_token)\n\n  render change: \"project:#{@project.id}\"\nend\n```\n\nIf you noticed, the last line of the method `show` reads `render change: \"project:#{@project.id}\"`.\n\nLet's break it down:\n\n`render` with `change` instructs Turbolinks 3 to render the response (instead of doing a normal page load).\n\n`change: \"project:#{@project.id}\"` instructs Turbolinks 3 to replace only the `div` with a matching `id` that can be found in the rendering `app/views/projects/show.html.slim`.\n\nAnd so, one by one, the empty \"Cards\" will be replaced by \"Cards\" with information.\n\nAs of this writing, Turbolinks 3's Partial Replacement technique looks really promising to me. In fact, before Turbolinks 3, I would write custom JS that sort of mimics the behavior of Partial Replacement. Hence I am really looking forward to the release of Turbolinks 5 as that means I don't need to write extra JS anymore.\n\nThere is a potential problem which I am keeping track of though: \n\nhttps://github.com/rails/turbolinks/issues/546\n## Parallel ~~Tests~~\n\nYou are probably familiar with [Parallel Tests](https://github.com/grosser/parallel_tests) but not so much of the gem that powers it: [Parallel](https://github.com/grosser/parallel).\n\nIf you look into the source code, you will notice that I am actually not storing anything in the database (except for projects). Hence in order to make API calls (`(GitHub + CI) * Number of Projects`) speedy, `Parallel` is used to parallelize the API calls.\n\nBack to `app/controllers/projects_controller.rb` again, where we first instantiate a `ProjectDecorator`, then we invoke `process_with` with the user's GitHub OAuth token:\n\n``` ruby\n# app/controllers/projects_controller.rb\n\ndef show\n  @project = ProjectDecorator.new(@project)\n  @project.process_with(current_user.oauth_account.oauth_token)\n\n  render change: \"project:#{@project.id}\"\nend\n```\n\nThe implementation of `process_with` is as follows:\n\n``` ruby\n# app/models/project_decorator\n\ndef process_with(oauth_token=nil)\n  @oauth_token = oauth_token\n\n  call_apis\nend\n```\n\nThe magic in this case happens in the private method `call_apis` which invokes other methods:\n\n``` ruby\ndef call_apis\n  Parallel.each(api_functions, in_threads: api_functions.size) { |func| func.call }\nend\n\ndef api_functions\n  [\n    method(:init_repos),\n    method(:init_ci)\n  ]\nend\n\ndef init_repos\n  client   = Octokit::Client.new(access_token: @oauth_token)\n  @_issues = client.issues(repo_name)\nend\n\ndef init_ci\n  @_ci =\n    case ci_type\n      when \"travis\"\n        Status::Travis.new(repo_name, travis_token).run!\n      when \"codeship\"\n        Status::Codeship.new(repo_name, codeship_uuid).run!\n      when \"circleci\"\n        Status::Circleci.new(repo_name, circleci_token).run!\n      else\n        Status::Null.new\n    end\nend    \n```\n\nIn the method `call_apis`, `Parallel` was used to fork 2 threads (`api_functions.size`), and to split and execute the methods in `api_functions` in separate threads.  \n\n``` ruby\ndef call_apis\n  Parallel.each(api_functions, in_threads: api_functions.size) { |func| func.call }\nend\n```\n\nUsing `method(:init_repos)` and `method(:init_ci)`, these two methods become function pointers that we can pass it as arguments to `Parallel.each` and be eventually invoked with `func.call`.\n\nAs such, to call both GitHub and CI apis for a project, no waiting is required to make the two api calls. With `Parallel`, it helped to reduce the time required for making all API calls, and thus made the dashboard load speedily.\n## \n\nI had fun building Dasherize as a toy utility project. \n\nI hope you enjoyed reading about some of the technical details too. :blush: Thanks for reading! \n\n@winston :pencil2: [Jolly Good Code](http://www.jollygoodcode.com)\n### About Jolly Good Code\n\n[![Jolly Good Code](https://cloud.githubusercontent.com/assets/1000669/9362336/72f9c406-46d2-11e5-94de-5060e83fcf83.jpg)](http://www.jollygoodcode.com)\n\nWe specialise in Agile practices and Ruby, and we love contributing to open source. \n[Speak to us](http://www.jollygoodcode.com/#get-in-touch) about your next big idea, or [check out our projects](http://www.jollygoodcode.com/open-source).  \n","author":{"url":"https://github.com/winston","@type":"Person","name":"winston"},"datePublished":"2015-10-08T10:37:04.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/5/jollygoodcode.github.io/issues/5"}

route-pattern/_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format)
route-controllervoltron_issues_fragments
route-actionissue_layout
fetch-noncev2:a0d1648e-7382-46fa-9061-05ec44439c38
current-catalog-service-hash81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114
request-idB59A:1DE745:840FB8A:B37C623:6A5E7733
html-safe-nonce438b9d67db1c25403a799d26004b3b44c29453c05d338d817861f0ab511d6a80
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCNTlBOjFERTc0NTo4NDBGQjhBOkIzN0M2MjM6NkE1RTc3MzMiLCJ2aXNpdG9yX2lkIjoiOTAxNjE1OTk1ODQ2NDM2MjI5MSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9
visitor-hmacf2b3d4212ab5a3ce13655fdf3b5f7663e8d9993d8db37c031680d01fe09db1a3
hovercard-subject-tagissue:110420144
github-keyboard-shortcutsrepository,issues,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///voltron/issues_fragments/issue_layout
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/jollygoodcode/jollygoodcode.github.io/5/issue_layout
twitter:imagehttps://opengraph.githubassets.com/fe60926b167967b7594a039773c787a6e81616ebf239952ca7d6926c06b24b23/jollygoodcode/jollygoodcode.github.io/issues/5
twitter:cardsummary_large_image
og:imagehttps://opengraph.githubassets.com/fe60926b167967b7594a039773c787a6e81616ebf239952ca7d6926c06b24b23/jollygoodcode/jollygoodcode.github.io/issues/5
og:image:altWe open-sourced Dasherize a few days ago. Dasherize is a simple, material-designed dashboard for your projects on which you can see: CI status of master branch (supports Travis CI, Codeship and Cir...
og:image:width1200
og:image:height600
og:site_nameGitHub
og:typeobject
og:author:usernamewinston
hostnamegithub.com
expected-hostnamegithub.com
None71950bbe6bf7e15662b868c102fed9d1682c29a05970d9b2daa2e4dd3522c52e
turbo-cache-controlno-preview
go-importgithub.com/jollygoodcode/jollygoodcode.github.io git https://github.com/jollygoodcode/jollygoodcode.github.io.git
octolytics-dimension-user_id5326832
octolytics-dimension-user_loginjollygoodcode
octolytics-dimension-repository_id39484578
octolytics-dimension-repository_nwojollygoodcode/jollygoodcode.github.io
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id39484578
octolytics-dimension-repository_network_root_nwojollygoodcode/jollygoodcode.github.io
turbo-body-classeslogged-out env-production page-responsive
disable-turbofalse
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release7514606601325843bc1c464d2d8bf5fe9af2c154
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/jollygoodcode/jollygoodcode.github.io/issues/5#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fjollygoodcode%2Fjollygoodcode.github.io%2Fissues%2F5
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
Code QualityEnforce quality at mergehttps://github.com/features/code-quality
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/open-source/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/open-source/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fjollygoodcode%2Fjollygoodcode.github.io%2Fissues%2F5
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fvoltron%2Fissues_fragments%2Fissue_layout&source=header-repo&source_repo=jollygoodcode%2Fjollygoodcode.github.io
Reloadhttps://github.com/jollygoodcode/jollygoodcode.github.io/issues/5
Reloadhttps://github.com/jollygoodcode/jollygoodcode.github.io/issues/5
Reloadhttps://github.com/jollygoodcode/jollygoodcode.github.io/issues/5
Please reload this pagehttps://github.com/jollygoodcode/jollygoodcode.github.io/issues/5
jollygoodcode https://github.com/jollygoodcode
jollygoodcode.github.iohttps://github.com/jollygoodcode/jollygoodcode.github.io
Notifications https://github.com/login?return_to=%2Fjollygoodcode%2Fjollygoodcode.github.io
Fork 4 https://github.com/login?return_to=%2Fjollygoodcode%2Fjollygoodcode.github.io
Star 136 https://github.com/login?return_to=%2Fjollygoodcode%2Fjollygoodcode.github.io
Code https://github.com/jollygoodcode/jollygoodcode.github.io
Issues 21 https://github.com/jollygoodcode/jollygoodcode.github.io/issues
Pull requests 0 https://github.com/jollygoodcode/jollygoodcode.github.io/pulls
Actions https://github.com/jollygoodcode/jollygoodcode.github.io/actions
Projects https://github.com/jollygoodcode/jollygoodcode.github.io/projects
Wiki https://github.com/jollygoodcode/jollygoodcode.github.io/wiki
Security and quality 0 https://github.com/jollygoodcode/jollygoodcode.github.io/security
Insights https://github.com/jollygoodcode/jollygoodcode.github.io/pulse
Code https://github.com/jollygoodcode/jollygoodcode.github.io
Issues https://github.com/jollygoodcode/jollygoodcode.github.io/issues
Pull requests https://github.com/jollygoodcode/jollygoodcode.github.io/pulls
Actions https://github.com/jollygoodcode/jollygoodcode.github.io/actions
Projects https://github.com/jollygoodcode/jollygoodcode.github.io/projects
Wiki https://github.com/jollygoodcode/jollygoodcode.github.io/wiki
Security and quality https://github.com/jollygoodcode/jollygoodcode.github.io/security
Insights https://github.com/jollygoodcode/jollygoodcode.github.io/pulse
Dasherize, Turbolinks 3 and Parallelhttps://github.com/jollygoodcode/jollygoodcode.github.io/issues/5#top
Bloghttps://github.com/jollygoodcode/jollygoodcode.github.io/issues?q=state%3Aopen%20label%3A%22Blog%22
https://github.com/winston
winstonhttps://github.com/winston
on Oct 8, 2015https://github.com/jollygoodcode/jollygoodcode.github.io/issues/5#issue-110420144
Dasherizehttps://github.com/jollygoodcode/dasherize
http://www.dasherize.com
READMEhttps://github.com/jollygoodcode/dasherize#origin
Turbolinks 3https://github.com/rails/turbolinks
Partial Replacementhttps://github.com/rails/turbolinks#partial-replacement-30
https://cloud.githubusercontent.com/assets/2112/10364137/8a0ebf1c-6deb-11e5-9470-7aa9240cdd83.gif
turbolinks/turbolinks-classic#546https://github.com/turbolinks/turbolinks-classic/issues/546
Parallel Testshttps://github.com/grosser/parallel_tests
Parallelhttps://github.com/grosser/parallel
@winstonhttps://github.com/winston
Jolly Good Codehttp://www.jollygoodcode.com
http://www.jollygoodcode.com
Speak to ushttp://www.jollygoodcode.com/#get-in-touch
check out our projectshttp://www.jollygoodcode.com/open-source
Bloghttps://github.com/jollygoodcode/jollygoodcode.github.io/issues?q=state%3Aopen%20label%3A%22Blog%22
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.