Sunday, August 10, 2008

Site updated, latest source in SVN

I've updated the site with a couple of bug fixes.  Mainly smallish things that make using the site more difficult than it needs to be.

The more exciting news is that I've finally committed the latest version of the site.  The source in SVN is almost a complete rewrite of the original release.  It's now using Monorail+AspViewEngine+Gaia.  I believe it's the only site out in the wild using Gaia with Monorail.


Saturday, August 2, 2008

Uploading bugfix release today

Well, no new features but there are a few bug fixes that are going to hit the site today.   Yay bug fixes!  This will probably be the last release until Mono 2.0 is released, at that point I'll probably do a big update, pushing some new features, the latest version of Gaia and Mono 2.0 (Right now I am using a locally patched version of Mono :-s).

Other than that, I'll probably be focusing on content creation for the next little bit.  The site seems to be in pretty good shape, but it's hard to tell how well things will handle lots of content.....so I guess that means I need to create lots of content, or convince lots of people to little bits of content, or more ideally, convince lots of people to create lots of content.

Sunday, April 20, 2008

Roadmap Tweaking

Last night I finished reading Building Scalable Web Sites: Building, scaling, and optimizing the next generation of web applications. Definitely a useful read and I will be using some of the books advice on Grurrah.

Google code's wikis are down right now, but later today I plan on adjusting the Grurrah roadmap a little bit. The main thing I will be doing is pushing back the initial release until right around the 1st of may and creating another release mid may. I'd like to push the initial release back so I can focus on some security issues and I would also like to upgrade Grurrah to the Gaiaware Glory Release. It will be nice to use Glory's improved menu bar for adding search to Grurrah and I'd like to try using it for the WYSIWYG editor as well.

I'll also push back the facebook integration a little bit, just because facebook is a wild animal and I am afraid of unleashing it on my servers before I am sure things will scale well. I think Grurrah should be able to scale out pretty well, since I am (now) avoiding a lot of the common problems people have when trying to scale.

Saturday, April 12, 2008

The Comments control

Not in SVN yet but I am pretty happy with the state of the comments control. My goal was to make things super simple for users. No edit, no delete (although, I might add delete) and no replies. Just a nice little stream of consciousness on the bottom of pages. Inspired by the simplicity of twitter.

The more I think of it, the more I feel comments might be the most important part of Grurrah, since it gives people a way to communicate about Grurrahs.



Everything is nice and AJAXy thanks to Gaia. There are ten comments per a page displayed, and you can go to older/newer comments without a page refresh. Also adding a new comment doesn't cause a page refresh. Oh, and the Add Comment textbox thingy hides and expands without refreshing. Definitely makes the user experience a lot nicer than your standard click and wait webpage. Plus reduces strain on my webserver, which is pretty important considering the resource limited environment I am running in right now.

Friday, April 11, 2008

Lions, Tigers, and Bears

There is a little something of everything in the upcoming Grurrah code drop. I've rectified some performance issues, fixed some stability issues, ammended some minor UI issuelets, cleaned up some code, added some new backend enhancements AND implemented some new features.

Here's a quick rundown of the more exciting stuff:
1. User pages. A user page will display what Grurrah's a user is doing and which one's they want to do. Users will also be allowed to upload profile pictures which will be used in:

2. Comments! Users will be able to add comments to each Grurrah.

3. Search!!!! The indexer has actually been running on the server for a week now. I've had it running in the background so I could figure out if there are any disastrous side effects to having the indexer running. Doesn't seem to be any so far. Soon grurrah.com will sport a search box in the menu bar at the top of every page.

4. Memcached. OK, not sure if everyone finds this exciting but I do. Grurrahs are now cached in Memcached which should greatly improve performance once grurrah is under heavy load. Going to save a lot of strain on the DB.

Less exciting stuff:
Fixed the JS for the ratings control to be a lot more useable (you don't get the hand icon when you mouse over the stars after submitting a rating)

Cleaned on MySqlConnections, we aren't leaving any open anymore.

Fixed bug where clearing tags wouldn't let you set tags anymore

Cleaned up a lot of the object model code, getting it out of Visual Studio style and putting it in Jackson style.

When will you get to see this stuff?
Everthing should be in SVN tomorrow. I can't push it to grurrah.com yet, but I am thinking about setting up a dev.grurrah.com that is always running the latest and greatest. It really depends how much time it will take me to set that up. I only have so many cycles, and I don't want to dedicate too many of them to server administration when there are still a bunch of important features to implement.

I'd like to have these new features live on Earth day, but that might not be possible.

Monday, March 31, 2008

Getting started on search

Spent an hour tonight playing with Lucene.Net. I've got a real simple command line version of search going. I also think I came up with a good idea for queueing indexes. Hopefully this weekend I'll have time to hack on that. For now search seems like an easier problem than I expected though.

Here's my real simple indexer and searcher:



using System;
using System.Configuration;
using System.Collections.Generic;

using Lucene.Net.Index;
using Lucene.Net.Documents;
using Lucene.Net.Analysis.Standard;

using MySql.Data.MySqlClient;


namespace Grurrah.Tools {

public class Indexer {

private static readonly int GrurrahIdColumn = 0;
private static readonly int GrurrahNameColumn = 1;
private static readonly int EntryTextColumn = 2;
private static readonly int TagNameColumn = 3;
private static readonly int RatingAvgColumn = 4;

private static readonly string QueryString = "SELECT Grurrahs.id, Grurrahs.name, Entries.text, Tags.name, AVG(user_grurrah_ratings.rating) FROM Grurrahs " +
"RIGHT JOIN Entries ON Grurrahs.id = Entries.grurrah_id AND Grurrahs.entry_index = Entries.entry_index " +
"LEFT JOIN tag_map ON Grurrahs.id = tag_map.grurrah_id LEFT JOIN Tags on tag_map.tag_id = Tags.id " +
"LEFT JOIN user_grurrah_ratings ON Grurrahs.id = user_grurrah_ratings.grurrah_id GROUP BY Grurrahs.id, Tags.name";


private static MySqlDataReader reader;

public static void Main ()
{
LoadData ();
IndexData ();
}

private static void LoadData ()
{
ConnectionStringSettings cs = ConfigurationManager.ConnectionStrings ["Read"];
MySqlConnection con = new MySqlConnection (cs.ConnectionString);

con.Open();

MySqlCommand cmd = new MySqlCommand (QueryString, con);
reader = cmd.ExecuteReader ();
}

private static void IndexData ()
{
IndexWriter writer = new IndexWriter ("Indexes", new StandardAnalyzer (), true);

while (reader.Read ()) {
if (reader [GrurrahNameColumn] == DBNull.Value)
continue;
writer.AddDocument (IndexGrurrah ());
}

writer.Optimize ();
writer.Close ();
}

public static Document IndexGrurrah ()
{
Document doc = new Document ();

if (reader [RatingAvgColumn] != DBNull.Value)
doc.SetBoost (reader.GetInt32 (RatingAvgColumn));

doc.Add (new Field ("name", reader.GetString ("name"), Field.Store.YES, Field.Index.TOKENIZED));
doc.Add (new Field ("text", reader.GetString ("text"), Field.Store.YES, Field.Index.TOKENIZED));

return doc;
}
}
}




using System;
using Lucene.Net.Search;
using Lucene.Net.Documents;
using Lucene.Net.QueryParsers;
using Lucene.Net.Analysis.Standard;



namespace Grurrah.Tools {

public class Search {

public static void Main (string [] args)
{
if (args.Length < 1) {
Console.Error.WriteLine ("You must supply a query parameter.");
return;
}

IndexSearcher searcher = new IndexSearcher ("Indexes/");
QueryParser parser = new QueryParser ("text", new StandardAnalyzer ());
Query query = parser.Parse (args [0]);
Hits hits = searcher.Search (query);

for (int i = 0; i < hits.Length (); i++) {
Document doc = hits.Doc (i);
Console.WriteLine ("{0}: {1} -- {2}", doc.Get ("name"), doc.Get ("text"), hits.Score (i));
}

searcher.Close ();
}
}
}

It's official, Grurrah.com is open source

Just checked the first source code drop into svn.