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,565
|
Comments: 51,185
Privacy Policy · Terms
filter by tags archive
time to read 1 min | 112 words

Well, looks like I don't have free bandwidth :-) The recent release of Hibernating Rhino #8 has made it clear, since it resulted in a bill.

Now I am looking for a solution for that. We are talking about files on the ~100 - 200 MB range, downloaded tens of thousands of times, over long period of time.

I thought about setting up a torrent server, but I can't find any viable torrent server for Windows, and I don't want to run the torrents from my machine. (I have a server available, if needed)

The other option is hosting it someplace that doesn't mind the bandwidth. Any suggestions?

time to read 1 min | 135 words

Here is a challenge, get this to work:

///<summary>
/// Executes the given handler when the instance is disposed
/// of using the Dispose(instance);
/// Note: Doesn't cause memory leak
///</summary>
public void OnDisposable(object instance, Action<object> action);

///<summary>
/// Executes the previously registered Action for this
/// instance
///</summary>
public void Dispose(object instance);

The key part here is to get this to work without causing a memory leak. Furthermore, assume that you need to handle this scenario as well without causing a leak:

object instance = new object();
OnDisposable(instance, delegate(object obj)
{
    Console.WriteLine("Disposing of {0}", obj);
});
time to read 1 min | 180 words

// We create a class for the macro, the class name is
// meaningful, [macro name]Macro allows us to later refer
// to the macro using just [macro name].
// Note that we inherit from AbstractAstMacro
class UnrollMacro(AbstractAstMacro):

	// Here we perform the actual compiler manipulation
	// the compiler hands us a macro statement, and we have
	// to return a statement back, which will replace it.
	override def Expand(macro as MacroStatement) as Statement:
	
		// define a block of code
		block = Block()
		
		// extract the second parameter value
		end = cast(IntegerLiteralExpression, macro.Arguments[1]).Value
		
		for i in range(end):
			// create assignment statement, using the block: trick 
			// and add it to the output
			statements = [|
				block:
					$(macro.Arguments[0]) = $i
			|].Block
			block.Add(statements)
			
			// add the original contents of the macro
			// to the output
			block.Add(macro.Block)
			
		return block
And usage:
unroll i, 5:
	print i

Which will produce:

i = 0
print i
i = 1
print i
i = 2
print i
i = 3
print i
i = 4
print i
time to read 1 min | 120 words

I just got 3000% performance improvement. I got if by turning this:

public int GetLatestVersion()
{
	return SourceControlService.GetLatestChangeset(serverUrl, credentials);
}

To this:

public int GetLatestVersion()
{
	const string latestVersion = "Repository.Latest.Version";
	if (PerRequest.Items[latestVersion] != null)
		return (int) PerRequest.Items[latestVersion];
	int changeset = SourceControlService.GetLatestChangeset(serverUrl, credentials);
	PerRequest.Items[latestVersion] = changeset;
	return changeset;
}

PerRequest.Items maps to HttpContext.Current.Items (it is a bit more complicated than that, we have non IIS hosted version to consider, but that is the same thing).

If you are wondering what it the most critical thing that you can do to get good performance, look at remote calls in the application.

time to read 3 min | 482 words

Wow, that was a popular topic, just take a look at the comment thread. I'll do more of those in the future.

The code in question is:

public byte[] DownloadBytes(string url,
                            ICredentials credentials)
{
    WebRequest request = Util.SetupWebRequest(WebRequest.Create(url), credentials);

    using (WebResponse response = request.GetResponse())
    {
        using (Stream stream = GetResponseStream(response))
        {
            byte[] buffer = new byte[response.ContentLength];
            int current = 0;
            int read;
            do
            {
                read = stream.Read(buffer, current, buffer.Length - current);
                current += read;
            } while (read != 0);
            return buffer;
        }
    }
}

The code as written will result in data corruption. Now, people have found a lot of issues with this code. So many that I am considering doing a "production code" post about this.

The problem that I had in mind, which El Guapo correctly pointed at, is that this code relies on response.ContentLength to be accurate. There are innumerous reasons for it to be inaccruate (server not sending the header, chucking, etc).

The main issue, however, is that ContentLegnth represent the size of the payload on the wire. This is very important, because size_on_wire != actual_size. This happened to me when the server was using GZip compression to send files. The CLR Web API will automatically notify the server that they can accept gzip and deflate compressions, and they will decompress it behind the scene when it comes the time to read it. The result is that size on the wire is significantly smaller than the actual file size, but I blithely ignored everything else and read only the size on the wire.

It took me a while to track that, because the code that had this issue was an async file reader, and I initially assume that I had a threading issue there.

Ayende.com, Inc

time to read 2 min | 276 words

For a long time, there has been rumors about this blog and other action carried on under the pseudonym "Ayende Rahien".  More specifically, we refer to allegations of a team behind the "Ayende Rahien" persona.

We are now pleased to announce that after 3 years of unparallel success, the Ayende.com startup has received its second round of funding, and are now able to go public with the results of the experiment.

The entity known as "Ayende Rahien" is an AI simulations, built by Ayende.com Inc as the first wave of AI Sourcing. (Think outsourcing, but without having to deal with the accent.

Looking back at the last three years, the decision to direct the AI toward Open Source projects and contributing to them has been a major success in growing the capabilities of the AI. Although some kinks in the design of the AI caused some... issues with regards to language and culture, but recent success in incorporating the AI into the corporate world has made us decide that this is the right time to go public with this information.

This person, image, who up until now served as a human front to the UI, is actually an actor with some basic knowledge in programing and great capacity for regurgitation.

We feel that during the last two years we have successfully proven the AI capabilities in terms of software development, and are now looking for additional customers for its capabilities. For questions and inquiries on the subject, you can contact us at: ayende@ayende.com

Thanks,

The Ayende.com team

time to read 2 min | 285 words

There is a huge bug in this code, resulting in data corruption. Can you spot what it is?

public byte[] DownloadBytes(string url,
                            ICredentials credentials)
{
    WebRequest request = Util.SetupWebRequest(WebRequest.Create(url), credentials);

    using (WebResponse response = request.GetResponse())
    {
        using (Stream stream = GetResponseStream(response))
        {
            byte[] buffer = new byte[response.ContentLength];
            int current = 0;
            int read;
            do
            {
                read = stream.Read(buffer, current, buffer.Length - current);
                current += read;
            } while (read != 0);
            return buffer;
        }
    }
}

Hint, this has nothing to do with exception handling. Assumes that nothing goes wrong.

FUTURE POSTS

No future posts left, oh my!

RECENT SERIES

  1. Production Postmortem (52):
    07 Apr 2025 - The race condition in the interlock
  2. RavenDB (13):
    02 Apr 2025 - .NET Aspire integration
  3. RavenDB 7.1 (6):
    18 Mar 2025 - One IO Ring to rule them all
  4. RavenDB 7.0 Released (4):
    07 Mar 2025 - Moving to NLog
  5. Challenge (77):
    03 Feb 2025 - Giving file system developer ulcer
View all series

RECENT COMMENTS

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats
}