v0.7 Release – Explaining the Split Bug

As a part of one of my goals for this release I want to find a solution for a problem I have appropriately named the “split bug”. Let me explain what it is all about:

Sometimes merge changsets are showing up while others times they aren’t. It has me pretty confused. I wasn’t getting this error beforehand. Basically sometimes I’m getting an error with the Split() function which I’m using to get the rev, user and description for each entry. The error only occurs with some merge changsets, which means they don’t get shown.

Basically, the following is the code I’m using to parse merge changesets right now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//Check whether it is a merge changeset or not
if(pushData[i].MergeData != []) {
  for(var j = 0; j < pushData[i].mergeData.length; j++) {
    if(pushData[i].mergeData[j] != "") {
      var mergeStr = pushData[i].mergeData[j];
      for(var k = 0; k < pushData[i].mergeData[j].length; k++) {
        var actualMergeStr = mergeStr[k].split('|-|');
        var mergeC = actualMergeStr[0];
        var mergeUser = actualMergeStr[1];
        var mergeDesc = actualMergeStr[2];
 
        if(mergeDesc != pushData[i].desc) {
          var trScrollMerge = document.createElement("tr");
          trScrollMerge.className = trScroll.className;
          var tdScroll_MergeUser = document.createElement("td");
          tdScroll_MergeUser.width = "184px";
 
          //Create changset link 
          var tdScroll_MergeC = document.createElement("td");
            tdScroll_MergeC.innerHTML +=
            '<a href="/rev/' +
            mergeC.substring(0, 12) + 
            '">' + 
            mergeC.substring(0, 12) +
            '</a>'; 
 
          //Create bugLink  
          var merge_bugLink = createBuglink(mergeDesc);
 
          var tdScroll_MergeAuthorDesc = document.createElement("td");
          tdScroll_MergeAuthorDesc.innerHTML += '<strong>' + mergeUser + ' &mdash ' + merge_bugLink + '</strong>';
          trScrollMerge.appendChild(tdScroll_MergeUser);
          trScrollMerge.appendChild(tdScroll_MergeC);
          trScrollMerge.appendChild(tdScroll_MergeAuthorDesc);
          document.getElementById("titlePush").appendChild(trScrollMerge);
        }
      }
    }
  }
}

This is a very surprising development. Why is this bug popping up now? Was this bug always there or did I make some change to cause it to occur? All things I will have to explore. I think I will start by re-exploring what the JSON data contains. In particular, I need to look at what mergeData contains, in order to find a solution to this bug.

Posted in DPS911, Mercurial Project, Open Source | Tagged , | Leave a comment

v0.7 Release – The Scroll Bar Solution

As a part of one of my goals for this release I want to find a solution to the pesky scroll bar problem. I explained the problem and my futile attempts to find a solution in my previous blog post.

So, as I mentioned earlier Dave Humphrey had shown me a different way of looking at the problem. Basically, I want to load more entries until the scroll bar appears. Now, my problem is that I don’t know how you would do this in JavaScript. I asked around and did some research to find a solution. The following is what I came up with:

function fillPage() {
  start = ($("div").attr("id")) - 10;
  var vHeight = 0;
  if (document.documentElement) {
    vHeight = document.documentElement.clientHeight;
  } else {
    vHeight = document.body.clientHeight
  }
 
  if (document.body.offsetHeight &lt; vHeight) {
    //calculate how many times to run loadEntries
    for(var count = 0, offSetHeight = document.body.offsetHeight;
        offSetHeight &lt; vHeight;
        count++, offSetHeight += 180);
 
    if(count &gt; 0)
      loadEntries(count);
  }
}

I get the height of the body and then compare it to the offsetHeight. Basically, I keep on loading more entries until the body height and the body offsetHeight are equal. On larger screens the difference between these two properties will be bigger than on smaller screens.

To do this I increment count by 1 and offSetHeight by 180 each time through the loop. Why 180 you ask? Each time loadEntries(1) is called it loads 20 entries which is at least a height of 180px. Once offSetHeight equals vHeight I pass the value of count to loadEntries() and then according to the value of count more entries are loaded. When count is equal to one 20 entries are loaded, when its value is two then 40 entries are loaded and so on.

This solution completely fixes my problem. I’ve tested it on larger screens in the CDOT area and on my 15inch laptop.  The solution works flawlessly. I’m so glad to finally find a fix for this pesky issue. Unfortunately screenshots won’t be able to prove that this functionality works. I would have to take a video of it in action. For now you’ll have to take my word for it or download the patch (when I upload it) and see for yourself.

Posted in DPS911, Mercurial Project, Open Source | Tagged , , | 4 Comments

v0.7 Release – The Scroll Bar Problem

As a part of one of my goals for this release I want to find a solution to the pesky scroll bar problem. Let me explain:

The Problem

Basically, by default the pushlog only loads 10 entries, which doesn’t fill out the entire page and thus the scroll bar does not show up. Now, this means that when the user tries to scroll down (to load more entries) nothing happens as the scroll bar event doesn’t fire. You might be wondering why not just load more entries by default? Well, first of all that isn’t an elegant solution, it’s a cop out and second, different users have varying screen sizes and thus this solution is not feasible.

A dynamic solution is needed where, according to the users screen size, a varying amount of entries are loaded automatically to fill out the page so that the scroll bar appears.

Possible Solutions

This problem is quite frustrating, to be honest. I’ve tried various methods to solve this issue but none have worked ideally. So far, I’ve tried to approach this problem from one angle, using the onload attribute of the body tag through which you can pass in a function that is executed when the page loads. In this function, I call my OnScroll function that loads more entries according to the screen size. So basically a loop is required but this reveals a very frustrating issue. Any kind of loop in this function causes the browser to throw an unresponsive script error. Since, I absolutely have to have a loop to implement the desired functionality, this solution is useless.

Next, I tried to get rid of the unresponsive script error by using setTimeout() which delays the execution of a function by x milliseconds. This gets rid of the script error that the browser was throwing but the browser Gods were still unhappy, as Firefox decided to freeze on me for 10-15secs. Once these seconds passed by the browser unfroze but my solution still didn’t work (no entries were loaded). Basically, nothing happened!

So all in all my attempts to come up with an efficient solution have all been futile, so far.

New Idea

I had a talk with Dave Humphrey this week about this scroll bar problem. He came up with an interesting idea. He approached the problem from a different angle. What if you could get the browser to tell you whether the scroll bar is available or not. So all you would do is keep on adding new entries until the scroll bar appeared and then stop.

I hadn’t thought about the problem in the manner that Dave highlighted. I think he might be onto something here. I’ll have to look into how I can do this in JavaScript. I am certain that there is a way to know whether the scroll bar is present or not. This new lead sounds very promising!

Stay tuned! I’ll be blogging about my findings very soon!

Posted in DPS911, Mercurial Project, Open Source | Tagged , , , | Leave a comment

v0.7Release – Retrieving the Total Number of Entries

Earlier today I outlined the goals of my current release. One of the problems I was looking to fix was with the function, getMaxEntries(). The job of this function was to create an xmlHttpRequest() in order to retrieve the maximum number of push entries in the repository. The pushlog displays data in reverse chronological order and thus I need to know the maximum number of entries so that I know which entries to display first to maintain the same order.

For example in my test repository I have 2613 total entries. The first 10 entries are displayed by default so when the user scrolls down to load more data the very first entry shown would be #2603, then 2602 and so on. Previously, to retrieve the maximum number of entries I was using the following function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function getMaxEntries() {
  var entries = new XMLHttpRequest();
  var max = 0;
  entries.open('GET', '/json-pushes?startID=0&endID=1', true);
  entries.onreadystatechange = function() {
  if(entries.readyState == 4)  {
    if(entries.status != 404) {
      var entryData = JSON.parse(entries.responseText);
      max = entryData[1].max;
 
      start = max - 10;
    }
  } else 
      return 0;
  } 
  entries.send(null);
}

I didn’t really like this method of using an xmlHttpRequest() just to retrieve one value. I had to call this function onPageLoad() to calculate the maximum number of entries. This had to be done before my OnScroll function was called or various horrible errors would occur.

I’ve noticed something very unique about JavaScript. It doesn’t wait for one function to finish executing before going on to the next function. If your first function is taking too long, JavaScript will move on to your next function. Now, this feature was causing me quite a few headaches. As I said before, getMaxEntries() had to finish executing completely before the OnScroll function was called, otherwise things would go horribly wrong. getMaxEntries() sets the value of start, which is then used by loadEntries() to retrieve data (called OnScroll). Since getMaxEntries() was taking too long to execute, JavaScript was moving on to loadEntries() without setting the value of start, completely wrecking my logic.

Also, getMaxEntries() was causing Firefox to freeze for 10-15secs for reasons unknown to me. This way of calculating the max number of entries wasn’t very elegant and totally unacceptable. I needed to come up with a better solution.

The Solution

hgweb uses a template system called genshi. Basically, the maximum number of entries is calculated via a database query on the server side. In order to pass this server side variable to the client side I had to add the line 4 to pushloghtml() in hgpollerpushlog-feed.py:

1
2
3
4
5
6
7
8
9
10
    return tmpl('pushlog',
                changenav=changenav(),
                rev=0,
                max=query.totalentries,
                entries=lambda **x: changelist(limit=0,**x),
                latestentry=lambda **x: changelist(limit=1,**x),
                startdate='startdate' in req.form and req.form['startdate'][0] or '1 week ago',
                enddate='enddate' in req.form and req.form['enddate'][0] or 'now',
                querydescription=query.description(),
                archives=web.archivelist("tip"))

Now, this change ^ allowed me access to this variable on the client side. All I had to do was to use this format: {<var_name>} or #<var_name>#. However, one draw back as far as I know is that I can only access this varialble in HTML, not in JavaScript, which is a significant drawback.

So in order to retrieve this data I added an id attribute the following div tag in hg_templatesgitweb_mozillapushlog.tmpl:

1
<div id="#max#" class="page_header">

Now, I could set the value of start to the maximum number of entries:

1
start = $("div").attr("id");

Thus, I can easily pass the correct value of start to loadEntries(), which makes an xmlHttpRequest() to retrieve the correctly ordered data when the user scrolls down.

Posted in DPS911, Mercurial Project, Open Source | Tagged , , , , , , | Leave a comment

v0.7 Release Goals

It’s time for another release for hgweb. I had thought about working on a new feature this release by I’ve decided to push that back to the next release. This time around I completely want to focus on one bug, getting pushloghtml to show more than 10 entries at a time.

Why? Well, I’ve put out multiple patches for this bug and it’s still not perfect. I realize that in software development bugs will always pop up somewhere but I’m just not satisfied with where my solution for this bug is right now. I really want to push for a complete solution this time around. The following are my goals for this release:

  • The function which retrieves the total amount of entries in the database, getMaxEntries() is causing the browser to freeze. Find a solution for this problem
  • Initially only 10 entries are displayed which means that the scroll bar doesn’t show up and thus more entries can’t be loaded since the OnScroll event doesn’t get called. Solve this problem by dynamically loading enough entries, according to the users screen size, until the scroll bar appears. I’ve tried various solutions for this problem, none of which have worked well so far. I want to solve this once and for all
  • I’ve discovered a weird bug (I seem to have a weird talent of discovering obscure bugs) when displaying merge changesets. Some of them are not being displayed at all. Find a solution for this bug
  • I’ve noticed another possible bug with merge changesets where, sometimes the last entry in a merge changeset is repeated in the next entry. Now, is this is a bug or not? Note sure. I need to investigate
Posted in DPS911, Mercurial Project, Open Source | Tagged , , | Leave a comment

Using Gmail with hg’s Patchbomb Extension

I recently created a patch for the Mercurial Project and in order to submit the patch I had to use hg’s patchbomb extension. Unfortuantely that requires me to have SMTP on my system. I didn’t have that so either I needed to install SMTP or figure out a way to use Gmail. I decided to use Gmail but it took me a while to get it working because I couldn’t really find much help on the web. Since nobody seems to have explained how to do this properly I decided I’ll just put out a simple guide. Here it is:

  1. Open up your repo’s .hgrc file
  2. Add the following:

                                          [extensions]
                                          hgext.patchbomb =

                                          [email]
                                          from=[your_name] [<your_email>]
                                          method=smtp

                                          [smtp]
                                          host=smtp.gmail.com
                                          port=587
                                          username=[gmail_email_address]
                                          password=[gmail_password]
                                          tls=True

Posted in Open Source | Tagged , , | Leave a comment

v0.6 Release Complete

I’m finally done with my v0.6 release. This time around I’ve managed to put out a total of 5 patches for 3 bugs. The patch fix for bug 445560 was minor but needed. The second patch was for the Mercurial Project to fix hg annotate for their paper theme. This is my first contribution to the Mercurial project which will hopefully give all mercurial users access to a better hg annotate. The third patch was for bug 459727 to fix the bitrotting issue.

I have to say that I was able to get these patches working without much trouble which isn’t normally the case. I’m happy to say that I was more efficient in my work this time around. The only furstrating problem I had with this release was indenting issues when creating patches. I had to tinker with the patches quite a few times to get the indenting right. Nonetheless, another release is complete, the following are the important links:

All the patches have been posted . Please view the project page for more details.
Note: I’m having a bit of trouble emailing the patch for the paper theme using Mercurial’s patchbomb extension. The patch will be emailed tomorrow but for convenience the patch can be found on the project page

EDIT: The patch for the paper theme has been sent to the Mercurial developer’s mailing list.

Posted in DPS911, Mercurial Project, Open Source | Tagged | Leave a comment

v0.6 Release – Removing the Page Navigation Links from Pushloghtml

I’ve decided to remove the navigation links that appear at the top and the bottom of pushloghtml. This wasn’t part of my goals for this release but I’ve decided to add this at the last minute. The patch is for bug 459727, which loads more data OnScroll and thus makes the navigation links obsolete. There is no need for them to be there anymore.

 

Removing them was pretty simple. All I had to do was remove the following code from hg_templates/gitweb_mozilla/pushlog.tmpl

Page #changenav%navpushentry#

I had to remove the above line of code from two places to get rid of both the top and bottom navigation links. Taking these navigation links out removes the unneeded clutter from the page.

Posted in DPS911, Mercurial Project, Open Source | Tagged , , , | Leave a comment

v0.6 Release – Refactoring to Fix the Bitrotting Issue with Bug 459727

I had mentioned in my previous blog post that hgpoller/pushlog-feed.py had bitrotted. One of my goals for this release was to make changes to the current version of pushlog-feed.py so that my patch is no longer broken for bug 459727. I’ve finally made those changes, which mainly occur in pushes_worker(). The following is what this method looks like with my changes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def pushes_worker(query, repo):
    """Given a PushlogQuery, return a data structure mapping push IDs
    to a map of data about the push."""
    pushes = {}
    for id, user, date, node in query.entries:
        mergeData = []
        ctx = repo.changectx(node)
        if len(ctx.parents()) > 1:
          for cs in ctx.parents():
            mergeData.append(hex(cs.node()) + '|-|' + clean(person(cs.user())) + '|-|' + clean(cs.description()))
        if id in pushes:
            # we get the pushes in reverse order
            pushes[id]['changesets'].insert(0, node)
            pushes[id]['mergeData'].append(mergeData)
        else:
            pushes[id] = {'user': user,
                          'date': date,
                          'changesets': [node],
                          'formattedDate': util.datestr(localdate(date)),
                          'individualChangeset': hex(ctx.node()),
                          'author': clean(person(ctx.user())),
                          'desc': clean(ctx.description()),
                          'mergeData': mergeData,
                          'max': gettotalpushlogentries(conn)
                          }
    return pushes

Basically I had to pass in repo (web.repo) so that I could have access to repo.changectx(node). This now allows me access to ctx.parents() which I need to retrieve merge changeset data. I also went through the whole file and changed every instance where pushes_worker() was called so that repo was being passed in as a paramater along with query.

These are all the changes I needed to make to the server side code. Now I’ll have to examine the changes that were made to the client side which caused my patch to bitrot.

Posted in DPS911, Mercurial Project, Open Source | Tagged , , , , , | Leave a comment

v0.6 Release – Examining the Changes with hgpoller/pushlog-feed.py

I had mentioned in my v0.6 goals blog post that my patch for bug 459727 had bitrotted. Unfortunately significant changes were made to hgpoller which apparently broke my patch. I need to remedy this situation because all my server side functionality for this patch is in the pushlog-feed.py file.

I downloaded the latest hgpoller source code and had a look at the changes that had been made. The file has changed in quite a few places. It seems that the function that my patch alters has been changed as well. I’m talking about pushes_worker(), which is repsonsible for passing the data from the server side to the client side.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def pushes_worker(query):
    """Given a PushlogQuery, return a data structure mapping push IDs
    to a map of data about the push."""
    pushes = {}
    for id, user, date, node in query.entries:
		if id in pushes:
			# we get the pushes in reverse order
			pushes[id]['changesets'].insert(0, node)
		else:
			pushes[id] = {'user': user,
						  'date': date,
						  'changesets': [node]
					     }
	return pushes

Now, the problem is that I need access to web.repo within pushes_worker() so that I can call repo.changectx(node) but right now, I don’t have access to repo within the method. I’ll have to figure out a way to do that somehow.

Posted in DPS911, Mercurial Project, Open Source | Tagged , , , | Leave a comment