Updates from Benji York Toggle Comment Threads | Keyboard Shortcuts

  • Benji York 1:36 pm on June 18, 2013 Permalink | Reply  

    Juju GUI version 0.6.0 Released 

    We are happy to announce that the 0.6.0 release of the Juju GUI is available.

    Changes include:

    • New charm browser for finding available charms.
    • Visual styling changes.
    • The beginnings of a Go backend sandbox.
    • Bug fixes and improved CI reliability.
    • Automatic view portal zoom and centering.
    • Support for Google Analytics.
    • Linting of yuidoc comments.
    • Linting of copyright headers.
    • Linting of project documentation files.
    • Utility for recording and playback of websocket traffic for debugging.
    • Caching of search results.
    • Improved development HTTP server behavior.
    • Improved project documentation.
  • Benji York 3:59 pm on May 23, 2013 Permalink | Reply  

    Replaying websocket traffic 

    The Juju GUI communicates with Juju via a websocket. We wanted to be able to capture and replay the websocket traffic as a debugging aid, especially when tracking down memory leaks. We imagined that we would have to add client-side logging in order to capture the websocket traffic, but in doing my due diligence before implementing such a thing I decided to see if there was a way to capture the data without writing any code.

    It turns out that Chrome’s built-in network inspector panel will let you see the frames sent across a web socket but I could not find a built-in way to export the data. The best you can get is copy/paste the frame data.

    Unfortunately the copy/paste omits an important detail. Chrome indicates the direction of the data flow (from the client to the server or vice versa) as the color of each row (green for sent frames, white for received frames). That coloration is, of course, lost when the text is copied.

    This would seem to be a critical failure, but I realized that given the constraints of the protocol spoken between the GUI and Juju, we can always infer the direction of communication from the message itself.

    After realizing this I built a proof-of-concept program that, given a copy/pasted log from Chrome will replay a websocket session. It waits for the GUI to make a request and then parrots the response read from the log. If the GUI makes a request that does not match the log the server raises an exception and the party is over.

    This is how you collect a websocket traffic log that can be replayed:

    1. Open a new tab in Chrome
    2. Open the developer tools (Control-Shift-i)
    3. Select the “Network” pane
    4. Click the “Websockets” filter at the bottom of the pane
    5. Navigate to the GUI (e.g., localhost:8888)
    6. Perform the actions you want logged.
    7. Click on the single “ws” entry on the left of the Network pane.
    8. Select the “Frames” tab to the right.
    9. Click on the first entry in the frames table.
    10. Type Control-a to select all.
    11. Open a text editor and middle-click to paste the log.
    12. Save the log to a file.

    Note: If you are taken to the “Sources” view by a breakpoint being triggered you need to disable breakpoints by selecting the “Sources” pane and clicking on the pause symbol in a stop sign at the bottom of the pane until it is grey (i.e., no stopping on breakpoints).

  • Benji York 1:35 pm on May 17, 2013 Permalink | Reply  

    Checking for Memory Leaks in Chrome 

    Here is a quick procedure for checking for memory leaks (or DOM leaks) in Chrome.

    • load the app/page in question
    • open the developer tools (ctrl-shift-j)
    • switch to the “Timeline” pane
    • start the memory timeline (click the little grey circle)
    • trigger garbage collection (click the trash can icon)
    • clear the timeline (click the slashed-circle icon)

    Now you have a good baseline to compare against. The next step is to perform the action you want to check for leaks. After that you can do the checking proper:

    • trigger garbage collection
    • expand the time range of the bottom graph by double-clicking on the bar just below the label for the “Timeline” pane (this expands the time window selector to “all time” (but it does not track, so new data are not graphed))

    Now you can look at the bottom graph to see if the DOM nodes, event handlers, and Document counts returned to the baseline or not.

    To compare heap memory usage you can follow these steps.

    • load the app/page in question
    • open the developer tools (ctrl-shift-j)
    • switch to the “Profiles” pane
    • take a heap snapshot (garbage is collected before the snapshot is taken)
    • perform the action you want to check for leaks
    • take a second heap snapshot

    Now you can select the second snapshot and change “Summary” to “Comparison” to see the two snapshots compared.

  • Benji York 8:41 pm on April 23, 2013 Permalink | Reply  

    I’ve been investigating the speed of various things in the hopes of speeding up the deploying of a charm from a branch of the GUI. Here are some things I found.

    Downloading the release (27M) from Launchpad via my home connection averages about 10 seconds, downloading it to an EC2 instance takes about 20 seconds.

    Downloading the release from an S3 bucket via my home connection takes about 30 seconds and is pretty variable. Downloading the release from an S3 bucket to an EC2 node takes between 13 seconds and over 3 minutes (highly variable).

    Running just the NPM installation portion of a GUI build with empty NPM caches takes over 4 minutes on an m1.small instance and right at 2 minutes for an m1.xlarge instance, presumably because of the faster disk performance on the xlarge. It takes 2 minutes on my connection/machine as well.

    Running the NPM installs with a full cache and setting cache-min to 99999 takes just under 1 minute on an m1.small instance and averages 18 seconds on an m1.xlarge instance and locally.

    All of the above data suggests that we should capture the NPM cache and pre-populate it when deploying the charm against a branch. When deploying to an m1.small instance we should save about 2 minutes and when using an m1.xlarge we can save about 3 minutes and 20 seconds over an empty cache on an m1.small instance.

    • garyposter 4:14 pm on April 24, 2013 Permalink | Reply

      Cool, thank you.

      Interesting things to investigate further:

      • If you start an EC2 machine in an Australia or Asia region, how long does it take to download from Launchad?
      • If you put the S3 bucket in CloudFront (looks easy) what are the download times (home, ec2 in NA, ec2 in Asia/Australia)?
  • Benji York 5:11 pm on March 27, 2013 Permalink | Reply  

    Firefox locks up (100% CPU) when I turn on the “Web Console” (not the “Error Console”).

    • Benji York 5:35 pm on March 27, 2013 Permalink | Reply

      It turns out that the lock-up only happens in the Juju-GUI. Other pages do not exhibit the problem.

    • Benji York 5:41 pm on March 27, 2013 Permalink | Reply

      Another detail: it un-freezes after approximately 60 seconds and then appears to act normally.

    • Benji York 5:54 pm on March 27, 2013 Permalink | Reply

      After un-freezing it generates this error, which would seem to be related: “InternalError: allocation size overflow.”

      Oddly, the time stamps in the error log show the pause happening just after the above message is logged, but it was not visible during the freeze. Perhaps cleaning up after the error is what is taking so long. The last item displayed in the log during the hang was: “GET https://ec2-54-224-116-8.compute-1.amazonaws.com:17070/ [HTTP/1.1 101 Switching Protocols 207ms]”

    • Benji York 6:04 pm on March 27, 2013 Permalink | Reply

      Wow, it appears that a call to console.log() (which I added to try to debug a different issue) is the cause. Once I removed that line the hang went away.

    • Benji York 6:26 pm on March 27, 2013 Permalink | Reply

      The reason the console.log() call was using so much memory was that it was in a function that was incorrectly bound to an event (by me in a different branch) and the wrong thing (an instance of the Environment) was being passed to the event handler. That instance is huge, so stringifying it apparently used too much memory.

      Issue solved.

Compose new post
Next post/Next comment
Previous post/Previous comment
Show/Hide comments
Go to top
Go to login
Show/Hide help
shift + esc