2011-07-13 15 views
1

SharpSVNを使用して、プログラムでSVNリポジトリにアクセスします。これで、svn://またはhttp:// urlsを介したローカルリポジトリへのアクセスが非常に遅いという問題があります。すべてのアクセスには少なくとも1秒が必要で、アプリケーションは多数のプロパティとディレクトリリストを取得する必要があります。SharpSVNローカルホストへの接続レート制限?

2つの異なるマシンで問題を再現できます。両方ともWindows 7 32ビットであり、同じドメインにあります。 SVNサーバーはhttp:// URLのVisualSVN 2.1.9、svn:// URLのCollabNet 1.6.17です。これは、 "localhost"経由での接続とホスト名による接続で表示されます。私たちのC#アプリケーション、IronPythonを使った小さなテストベッドアプリ、そしてSharpSvn svn.exeコマンドを呼び出すときに表示されます。

この問題はリモートリポジトリ(LinuxとWindows XPの両方のサーバ)にアクセスするときには発生しません。ここでは、各アクセスは0.01秒と0.08秒の間です。これはネットワークの待ち時間のために予想されます。この問題は、file:// urls経由でローカルリポジトリにアクセスする場合や、CollabNetの "ネイティブ" svnコマンドラインツールを使用してリポジトリにアクセスする場合にも発生しません。

私の質問は:Windows 7または.NETまたはSharpSVNローカルホスト接続にのみ適用されるいくつかの組み込み制限がありますか?

(追加:私は今System.Net.Sockets.TcpClientを使って小さなC#のテストプログラムを経由して接続する際にこの制限にも適用されることが判明:

サーバー:

using System; 
using System.IO; 
using System.Net; 
using System.Net.Sockets; 

namespace TcpSpeedServer 
{ 
    class Program 
    { 
     public static void Main() 
     { 
      Int32 port = 47011; 
      IPAddress localAddr = IPAddress.Parse("127.0.0.1"); 

      var server = new TcpListener(localAddr, port); 
      server.Start(); 

      Console.WriteLine("Listening on {0} : {1}", localAddr, port); 

      ulong count = 0; 
      // Enter the listening loop. 
      while(true) 
      { 
       using (var client = server.AcceptTcpClient()) { 
        Console.WriteLine("Connected: {0} {1}!", count, client.Client.RemoteEndPoint); 
        count += 1; 

        using (var stream = client.GetStream()) { 
         using (StreamWriter writer = new StreamWriter(stream)) 
          using (StreamReader reader = new StreamReader(stream)) 
         { 
          string query = reader.ReadLine(); 
          writer.WriteLine("GET/HTTP/1.0"); 
          writer.WriteLine(); 
          writer.Flush(); 
         } 
        } 
       } 
      } 
     } 
    } 
} 

クライアント:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net.Sockets; 
using System.Threading; 

namespace TcpSpeedTest 
{ 
    class Program 
    { 
     const bool ASYNC = false; 
     static DateTime s_now; 
     public static void Main(string[] args) 
     { 
      var liste = new List<object>(); 
      s_now = DateTime.Now; 
      for (int i=0; i < 100; i += 1) { 
       if (ASYNC) 
        ThreadPool.QueueUserWorkItem(connect, i);    
       else 
        connect(i); 
      } 

      Console.WriteLine("outer: " + (DateTime.Now - s_now)); 
      Console.ReadLine(); 
     } 

     private static void connect(object i) 
     { 
      DateTime now = DateTime.Now; 

      using (TcpClient client = new TcpClient("localhost", 47011)) 
      { 
       var stream = client.GetStream(); 
       using (StreamWriter writer = new StreamWriter(stream)) 
        using (StreamReader reader = new StreamReader(stream)) 
       { 
        writer.WriteLine("GET/HTTP/1.0"); 
        writer.WriteLine(); 
        writer.Flush(); 
        string result = reader.ReadLine(); 
       } 
      } 
      Console.WriteLine(string.Format("inner: {0} - {1} - {2}", i, DateTime.Now - now, DateTime.Now - s_now)); 
     } 
    } 
} 

だから、この問題は、特定の転覆ではないように思われる。)

広告dition2:WindowsのMono 2.10でクライアントを実行すると、問題は表示されません。したがって、.NETフレームワークに固有のようです。

追加3:IPv6関連の問題のようです。サーバーはIPv4だけをリッスンしますが、ホスト名もIPv6に解決されます。これで、OSコードが内部的にIPv6接続を試行し、接続をリセットした後、1秒間待ってからIPv4に戻ってしまうようです。そして、この試合は1回の接続試行ごとに繰り返されます。 http://msdn.microsoft.com/en-us/library/115ytk56.aspx TcpClient(ヒントのためのMSDNフォーラムのAndreas Johanssonのおかげで)のドキュメントです。Apacheで使用されているAPRも同様のメカニズムを使用しているようです。

+0

あなたがWiresharkのか、Micrsoftネットワークモニタを使用してネットワークトラフィックを分析したことがありますか?サーバーが追加のユーザー情報やタイムアウトなどを取得しようとしている可能性もあります。 –

+0

@トーマス:サーバーがこのような試みをするとは思わない。これはネイティブのsvn.exeにも影響するからだ。そして、TcpClientとTcpListenerを使って2つの小さなC#テストプログラムを試しました。各接続で同じ1秒の遅延があります。 – MarkusSchaber

+0

テスト中にアンチウィルスクライアントを無効にしようとしましたか? –

答えて

2

追加3は、問題の解決方法です。これを修正するには、DNS/hostsファイルをIPv4アドレスに解決するか、IPv6サーバを動作させるかのいずれかを行います。

あなたのようなC:\Windows\System32\drivers\etc\hosts何かに入力することができます。

127.0.0.1 localhost-ipv4 

そして接続するためにその名前を使用します。

また、svnserveにIPv6アドレスを聞かせることもできます。 svnserveオプション[1]がIPv6にデフォルト設定されているので、起動パラメータはおそらく--listen-hostです。これを削除してください。存在しない場合はIPv6で実行してください。

同じではApacheウェブサーバのために行うことができます。

Listen 0.0.0.0:80 
Listen [::]:80 
+0

ヒントのおかげで。私はWindowsの内部ホストファイルを混乱させるように私たちのソフトウェアをユーザに尋ねることができるとは思っていません(ほとんどが企業環境にあり、管理者権限を持っているとは限りません)。しかし、SVNサーバーがIPV6対応環境でIPV6を好むべきであるという事実を文書化することは良い考えです。私は、ホストがIPv6アドレスを解決することができるネットワークがあるのを恐れているが、ルータはIPv6パケットを渡さない... – MarkusSchaber