Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Statistics api #296

Merged
merged 55 commits into from
Feb 18, 2014
Merged

Implement Statistics api #296

merged 55 commits into from
Feb 18, 2014

Conversation

ammeep
Copy link
Contributor

@ammeep ammeep commented Jan 9, 2014

Fixes #294

💃

Todo

  • Implement get contributors list
  • Implement get commit activity data
  • Implement get number of additions and deletions per week
  • Implement get weekly commit count
  • Implement get commits per hour
  • Handle 202, 200 for queued jobs
  • Tests

/// <param name="owner">The owner of the repository</param>
/// <param name="repoName">The name of the repository</param>
/// <returns>A list of <see cref="Contributor"/></returns>
public Task<IEnumerable<Contributor>> Contributors(string owner, string repoName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a "repo". 😛 We generally use name. If it's not clear that it's a repository, I'd prefer repositoryName

@haacked
Copy link
Contributor

haacked commented Jan 10, 2014

It's a good start!

@ammeep
Copy link
Contributor Author

ammeep commented Jan 11, 2014

These set of API's are a little different to what we already have in that the operations are expensive. On the first request the calculation of the stats is queued up and you are returned a 202. You retry the request until the job is complete and a 200 is returned.

Should Get be responsible for tracking the 202, and 200. Or do we provide a pair of operations - one to queue the job, and another to wait for its completion?

The downside with the latter - the 'wait for completion' method would still need to take into account that the stats might need to be recalculated server side (which will happen on each push to master)

I prefer the first option, but does anyone have any thoughts on how we want this to look on our client API?

@haacked
Copy link
Contributor

haacked commented Jan 11, 2014

I like the first option. With the observable API, we could have calling Dispose on the subscription cancel subsequent requests.

@shiftkey
Copy link
Member

I prefer the first option because it takes away the pain of having to implement the "poll until you get a 200" logic - which could be implemented in wildly different ways by different developers causing all sorts of headaches...

@pmacn
Copy link

pmacn commented Jan 11, 2014

Just a suggestion. You might want to make sure that the client methods (the non-reactive ones, not sure how Rx deals with cancellation yet) have overloads that take cancellation tokens if the calls could take long enough that a client would want to cancel.

@shiftkey
Copy link
Member

@pmacn 👍

@ammeep
Copy link
Contributor Author

ammeep commented Feb 3, 2014

One question I have - this API is not exactly user friendly. It likes to use arrays of ints everywhere. I would be keen to add some smarts to the objects being returned so that these are useable. For example

Get the number of commits per hour in each day

Returns: [ [2, 14, 25], ......]
Which actually means:

Each array contains the day number, hour number, and number of commits:
0-6: Sunday - Saturday
0-23: Hour of day
Number of commits

What do people think if we beefed up the models being returned from the statistics client to make this a much more consumable/understandable object.

@shiftkey
Copy link
Member

shiftkey commented Feb 3, 2014

@ammeep .\build FixProjects to sync up the Mono* projects

@shiftkey
Copy link
Member

shiftkey commented Feb 3, 2014

It likes to use arrays of ints everywhere.

Yep, transforming this into a dataset that's easier to traverse is 💚 from me.

A quick way to get started would be to tailor the response based on the specific API you're calling, which seems like you're already on that path.

A crazy idea: encapsulate the data behind a more human-friendly API in the response.

public class PunchCardStats 
{
    public int GetTotal(DateTime pointInTime) { ... }
    public int GetTotal(DateTime startTime, TimeSpan timeSpan) { ... }
}

rather than exposing the array directly (well you could do that anyway)...

@ammeep
Copy link
Contributor Author

ammeep commented Feb 3, 2014

.\build FixProjects to sync up the Mono* projects

😍

A crazy idea: encapsulate the data behind a more human-friendly API in the response. rather than exposing the array directly (well you could do that anyway)...

This is exactly what I was thinking 💥 love it. I'm not fussed on exposing the underlying array, we should be able to wing it so that people don't need this.

@ammeep
Copy link
Contributor Author

ammeep commented Feb 16, 2014

Anyone keen to give this puppy a review? It seems there are a bunch of tests in master that are also broken in this branch. Debugger displays missing etc - I fixed up those added in this PR. Apart from that. Keen for feedback 👍

_jsonPipeline.DeserializeResponse(response);
return response;
}

// THIS IS THE METHOD THAT EVERY REQUEST MUST GO THROUGH!
async Task<IResponse<T>> RunRequest<T>(IRequest request)
async Task<IResponse<T>> RunRequest<T>(IRequest request, CancellationToken cancellationToken)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should pass this cancellation token into _httpClient.Send<T> to make the FxCop warning go away...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also that was the entire point of this change. My bad.

@shiftkey
Copy link
Member

Got those tests passing, now reading it a bit more closely

@@ -44,8 +44,12 @@ public void DeserializeResponse<T>(IResponse<T> response)

if (response.ContentType != null && response.ContentType.Equals("application/json", StringComparison.Ordinal))
{
var json = _serializer.Deserialize<T>(response.Body);
response.BodyAsObject = json;
// simple json does not support the root node being empty. Will submit a pr but in the mean time....
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shiftkey
Copy link
Member

A few little places in the new tests where parameters are crammed together, but I'm definitely into whitespace OCD now in terms of reviewing.

@shiftkey
Copy link
Member

I'm happy to merge this in as a first pass for the feature - we can refine the data we return to the user in the future based on what users would like.

Ping me when you're happy with the whitespace stuff and I'll :shipit:

@ammeep
Copy link
Contributor Author

ammeep commented Feb 18, 2014

we can refine the data we return to the user in the future based on what users would like.

👍

@shiftkey ping... I'm happy with this now.

shiftkey added a commit that referenced this pull request Feb 18, 2014
@shiftkey shiftkey merged commit caa6bd7 into master Feb 18, 2014
@shiftkey shiftkey deleted the ammeep/statistics-api branch February 18, 2014 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement Repository Statistics
4 participants