Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,546
|
Comments: 51,163
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 303 words

Well, it looks like I have run into some limits with dasBlog.

I have over 2,000 posts, and close to 1,200 files in my content directory. It gets to the points that just opening the directory has a noticable delay.
Trying to run dasBlog currently takes roughly 100% of the CPU, and takes forever. This is on my machine, by the way, so it is single user only.

Trying that on the server apperantly killed it. 

Profiling it shows that the fault is probably with the template processor, AddParsedObject and InitializeMacro. That is about all the information that I managed to get from VS profiler, I am currently trying out dotTrace, to see if it can gives me a better idea about what is going on there.

Using dotTrace, the picture is much clearer, it looks like the cost is in iterating over all the past entries, you can take a look here for the details:
dasblog-perf.png

I removed all the entries from July 06 and backward, and this seems to bring the blog to a working state again. This is a temporary measure only. I am not willing to give up 2+ years of blogging. I have uploaded the dtc (dot trace snapshot) here, if anybody is interested in taking a look I can provide the full backup history, which put dasBlog through the grinder.

At the same time, I am investigating Subtext, which may be more appropriate for my kind of blog. The main concerns are not breaking links (but it is acceptable to have redirect) and having to re-do the blog design.

time to read 1 min | 189 words

My current readership seems to have stabilized on around 3,500 readers a day (after a peak of about 5,500 a day after I got linked from ScottGu's blog).

After seeing the dramatic difference that such a link can cause, I decided to check how I can bring in more readers. The simplest thing is to get myself linked from the aggregations sites such as Digg, DotNetKicks, etc. Of course that the high goal there is to get slashdotted, but I'm leaving this tactic for the future :-)

Now, putting my own posts on those sites is sleazy, but there is no reason that I wouldn't make it easy for you to do it. So I added links to deli.cio.us, Digg and DotNetKicks on each post. I used dasBlog's ability to define custom macros, and this custom macro library.

The link contains all the information that you can want on this, but be aware that the macros shown there wouldn't work as-is. For some reason Vasanth forgot to put <% on the beginning of each macro.

Reading the logs

time to read 1 min | 99 words

I spent a couple of minutes now going over the logs, it's quite amazing what you can find there. It looks like my posts about Brail started a bit of interest, since I suddenly started to see searches for information about it.

Another interesting things is that I started to get a lot more readers ~2,800 a day in the browser, and ~1,300 a day from RSS aggerators. I'm not using those numbers for their numeric values, since they don't really mean much by themselves, but it's interesting about 1,000 more readers via the browser, and ~700 more in RSS.

time to read 18 min | 3550 words

Every once in a while you see a couple of messages from the guys that use a Blog with a DB backend post some wonderful statistics about their Blog. I couldn't be happier with dasBlog (can you say zero headache in over two years of using it?), but I really like the statistics abilities. Well, I like to think of myself as a developer, and as such, I can solve such problems. Put this together with the SQL stuff I've been doing lately, and that dasBlog has Web Services functionality, and the solution is obvious, isn't it?

I'm going to explain how I did it now, and then post the stats in the next post (along with some nice graphs, I hope.) The first thing that I did was to take my previous post about dasBlog's Web Services, and took it for a spin, here are the results:

import System

import System.Data

import System.Data.SqlClient

import CookComputing.XmlRpc

import newtelligence.DasBlog.Runtime.Proxies

 

user = "Ayende Rahien"

password = "Ayende@ayende.com"

start = DateTime.Now

 

log = IO.File.CreateText("log.txt")

dasBlog = BloggerAPIClientProxy()

dasBlog.Url = "http://www.ayende.com/Blog/blogger.aspx"

posts = dasBlog.metaweblog_getRecentPosts("",user, password, 1500)

print "Got ${posts.Length} posts from server"

using con = SqlConnection("""Data Source=.;AttachDbFilename=F:.mdf;Integrated Security=True;User Instance=True"""):

      con.Open()

      using command = con.CreateCommand():

            command.CommandText = "INSERT INTO BlogStats(Time, Title) VALUES(@time, @title)"

            time = command.Parameters.Add("time", SqlDbType.DateTime)

            title = command.Parameters.Add("title", SqlDbType.NChar)

            for post in posts:

                  try:

                        time.Value = post.dateCreated

                        title.Value = post.title

                        command.ExecuteNonQuery()

                  except e:

                        print "Error updated post: ${post.title}"

                        print e.Message

                        log.WriteLine(e.ToString())

                        log.WriteLine("--- --- ---")

print "Took ${DateTime.Now - start}"

 

time to read 4 min | 632 words

Did you know that dasBlog has a hierarchal categories with a beautiful way to represent them? I didn't until I visited Oren Ellenbogen's blog and saw how his categories looked. My immediate response was "Me Too! Me Too!", so I set out to learn the secret.

Turns out that this isn't such a big secret after all: Oren* told me that it's simply a matter of seperating the categories with '|'. There is also some css magic that goes along with it, but looking at Oren's site with the WebDeveloper Extention for Firefox quickly showed what I needed. (#1 tool for anyone who wants to develop for the web, in my opinion).

I changed a single post category, and it worked! Now I wanted to change all the rest of them. Hierarchal categories are the new thing, I hear, so I certainly wanted them for my blog. Ever for the old posts. The trouble is that I currently has over 600 posts. (When did I manage to post so much?) And I wasn't feeling like spending the rest of the weekend pouring over each and every one of them changing the categories. I immediately setup to find a programmatic solution to the problem.

The first thing I thought about was that dsaBlog has a programming interface using the Blogger API, but I never worked with it. I googled for a little bit and found the Xml-Rpc.Net library, which incidently comes with a blogger API sample. But apperantly the Blogger API doesn't let you update the categories of a single post, at least not in any way that a very curosry will show. The MetaWeblog API does however, so I used that. I compiled newtelligence.DasBlog.Runtime.Proxies\BloggerAPIClientProxy.cs to an assembly I named dasBlogger.dll (I could've also used the dasBlog assemblies, but it would've taken time to build them, so I just compiled it seperatedly).

I tested it and it worked! Then I had the really hard part, thinking about how to map my categories to hierarchal structure. Here is the code I ended up with, very simple to write and understand. But it doesn't work.  The problem is that dasBlog only return the last 30 posts, no matter what value you pass to it. I'm going to email Scott about it. Pursuing the source for dasBlog, I didn't see where this functionality is controled.

import System
import CookComputing.XmlRpc
import newtelligence.DasBlog.Runtime.Proxies

user = "Ayende Rahien"
password = "Ayende Rahien's Password"

categories = {
"Ayende.Utilities" : "Programming | Utilities",
"Blog" : "Website | Blog",
"Boo" : "Programming | Boo",
"Boo On Rails" : "My Projects | Brail",
"Books" : "Culture | Books",
"Brail" : "My Projects | Brail",
"Bugs" : "Programming | Bugs",
"dasBlog" : "Website | Blog | dasBlog",
"Evil" : "Miscellaneous | Evil",
"eXtreme Programming" : "Programming | XP",
"Humor" : "Humor",
"Miscellaneous" : "Miscellaneous",
"Movies" : "Culture | Movies",
"Music" : "Culture | Music",
"NHibernate Query Analyzer" : "My Projects | NHibernate Query Analyzer",
"Programming" : "Programming",
"Rhino Mocks" : "My Projects | Rhino Mocks",
"Website" : "Website",
"Windows" : "Programming",
"Writings" : "Culture | Writings"
}
log = IO.File.CreateText("log.txt")
dasBlog = BloggerAPIClientProxy()
dasBlog.Url = "http://www.ayende.com/Blog/blogger.aspx"
posts = dasBlog.metaweblog_getRecentPosts("",user, password, 999)
start = DateTime.Now
for post in posts:
try:
for i in range( len (post.categories) ):
newCategory = categories[ post.categories[i] ]
if newCategory is null:
print "'${post.categories[i]}' is an unknown category"
continue
post.categories[i] = newCategory
if len(post.categories) == 0:
post.categories = ("Uncategorized",)
dasBlog.metaweblog_editPost(post.postid, user, password, post, true)
print "Updated post: ${post.title}"
except e:
print "Error updated post: ${post.title}"
print e.Message
log.WriteLine(e.ToString())
log.WriteLine("--- --- ---")
print "Took ${DateTime.Now - start}"

 * Last time I checked there were more than 8,500 people in Israel named Oren, and 7 named Oren Eini (none of them is related to me, btw).

FUTURE POSTS

  1. Partial writes, IO_Uring and safety - one day from now
  2. Configuration values & Escape hatches - 4 days from now
  3. What happens when a sparse file allocation fails? - 6 days from now
  4. NTFS has an emergency stash of disk space - 8 days from now
  5. Challenge: Giving file system developer ulcer - 11 days from now

And 4 more posts are pending...

There are posts all the way to Feb 17, 2025

RECENT SERIES

  1. Challenge (77):
    20 Jan 2025 - What does this code do?
  2. Answer (13):
    22 Jan 2025 - What does this code do?
  3. Production post-mortem (2):
    17 Jan 2025 - Inspecting ourselves to death
  4. Performance discovery (2):
    10 Jan 2025 - IOPS vs. IOPS
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}