Transmission: [تحسين] كن أكثر ذكاءً عند نقل الملفات

تم إنشاؤها على ١٤ يوليو ٢٠١٩  ·  8تعليقات  ·  مصدر: transmission/transmission

بالنسبة لنظام التشغيل Windows ، يمكن أن يستخدم tr_sys_path_rename العلامة MOVEFILE_COPY_ALLOWED بدلاً من حلقة "القراءة والنسخ" المضمنة من util.c:tr_moveFile

ثم يمكن لإصدار Linux استخدام copy_file_range الأكثر حداثة بدلاً من تكرار كل منها.

ربما شيء من هذا القبيل:

size_t tr_sys_file_copy(tr_sys_file_t infile, tr_sys_file_t outfile, size_t len, tr_error** error )
{
        TR_ASSERT(outfile != NULL);
        TR_ASSERT(infile != NULL);
        bool ret = false;
        unsigned int flags = 0;
        size_t res;

        res = copy_file_range(infile, NULL, outfile, NULL, &len, flags);
        if (res) {
                return res;
        }      
        else {
                set_system_error(error, errno);  
                return res;
        }
}

وربما:

tr_sys_file_copy_fallback(tr_sys_file_t infile, tr_sys_file_t outfile, size_t len,  tr_error** error ) {
    TR_ASSERT(outfile != NULL);
    TR_ASSERT(infile != NULL);

    uint64_t bytesLeft = len;
    size_t const buflen = 1024 * 128; /* 128 KiB buffer */
    tr_sys_path_info info;
    while (bytesLeft > 0)
    {
        uint64_t const bytesThisPass = MIN(bytesLeft, buflen);
        uint64_t numRead;
        uint64_t bytesWritten;

        if (!tr_sys_file_read(infile, buf, bytesThisPass, &numRead, error))
        {
            break;
        }

        if (!tr_sys_file_write(outfile, buf, numRead, &bytesWritten, error))
        {
            break;
        }

        TR_ASSERT(numRead == bytesWritten);
        TR_ASSERT(bytesWritten <= bytesLeft);
        bytesLeft -= bytesWritten;
    }
    return bytesLeft;
}
core enhancement pr welcome

التعليق الأكثر فائدة

+1 لجعل نقل البيانات غير متزامن. يؤدي نقل ملفات التورنت الكبيرة بين أنظمة الملفات إلى قفل التطبيق بالكامل .

ال 8 كومينتر

ثم يمكن لإصدار Linux استخدام copy_file_range الأكثر حداثة بدلاً من تكرار كل منها.

لا يمكن القيام بذلك بمكالمة واحدة فقط (أو في حلقة بسيطة):

       If  file_in  is  a  sparse  file, then copy_file_range() may expand any
       holes existing in the requested range.  Users may benefit from  calling
       copy_file_range()  in  a  loop,  and  using  the lseek(2) SEEK_DATA and
       SEEK_HOLE operations to find the locations of data segments.

(man copy_file_range)

من الناحية المثالية ، يجب أن نتأكد من قفل واستخدام sendfile () بشكل صحيح في سلسلة منفصلة.

هذا يشبه إلى حد كبير رمز "نقل الملف" الحالي عندما
فشل rename . هذا لا يحتفظ بالأقسام المتفرقة أيضًا ، لذلك لم أفعل
تعتبر هذه مشكلة عند استبدالها.

في الأحد 14 يوليو 2019 الساعة 10:41 مساءً كتب andreygursky [email protected] :
>

ثم يمكن لإصدار Linux استخدام copy_file_range الأكثر حداثة بدلاً من تكرار كل منها.

لا يمكن القيام بذلك بمكالمة واحدة فقط (أو في حلقة بسيطة):

   If  file_in  is  a  sparse  file, then copy_file_range() may expand any
   holes existing in the requested range.  Users may benefit from  calling
   copy_file_range()  in  a  loop,  and  using  the lseek(2) SEEK_DATA and
   SEEK_HOLE operations to find the locations of data segments.

(man copy_file_range)

من الناحية المثالية ، يجب أن نتأكد من قفل واستخدام sendfile () بشكل صحيح في سلسلة منفصلة.

-
أنت تتلقى هذا لأنك قمت بتأليف الموضوع.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو اعرضها على GitHub ، أو قم بكتم صوت الموضوع.

هذا لا يحتفظ بالأقسام المتفرقة أيضًا ، لذلك لم أفعل
تعتبر هذه مشكلة عند استبدالها.

وينقصه التخصيص المسبق للملفات العادية.

بلى. هذا ايضا. السلوك السيئ الحالي لـ "نقل الملف" كافٍ للتسبب في أحمال سخيفة في بعض عمليات الإعداد. إذا كان ذلك ممكنًا ، فيبدو أن الحل البديل في glibc copy_file_range هو تطبيق أفضل أيضًا.

لقد لعبت مع هذا. من الصعب الوصول بطريقة صحيحة عبر الأنظمة الأساسية: لا يبدو أن هناك أي واجهة POSIX لنسخة داخل kernel. لكنني أعتقد أن الأمر يستحق غلافًا خاصًا لكل نظام تشغيل لأنه نظرًا لأن أنظمة الملفات تصبح أكثر كفاءة في النسخ ، فإننا نريد الوصول إلى هذه الميزات تلقائيًا.

لديّ تطبيق أساسي قيد التشغيل على MacOSX و FreeBSD ولكني بحاجة إلى إعداد عدد قليل من الأنظمة الأخرى لاختباره.

أعتقد أن هذا العمل متعامد لجعل الملف يتحرك بشكل غير متزامن. لا ينبغي للمرء أن يقف في طريق الآخر. بالنسبة للمشاريع التطوعية ، فإن زحف النطاق هو عدو الإنتاجية.

التغييرات هنا: https://github.com/transmission/transmission/compare/master...RobCrowston : kernelcopy-wip

باختصار ، أقوم بإنشاء تجريد جديد يسمى tr_sys_path_copy (). (ذهبت بنسخة بدلاً من النقل لأنه عندما نجعل هذه العملية غير متزامنة ، قد يكون من الضروري الاحتفاظ بالملف الأصلي لفترة غير محددة من الوقت بعد اكتمال النسخة لإغلاق مقابض الملفات في سلاسل أخرى.)

حتى الآن ، قمت بتجميع وتشغيل الاختبار الجديد (نقل - نسخة تجريبية) على نظام التشغيل MacOS 10.15.1 ، و Windows Server 2016 ، و Linux 5.0 (Ubuntu 19.05) ، و Linux 5.3 (Arch 2019-12-03) ، و FreeBSD 12.1 (يستخدم مساحة المستخدمين الاحتياطية) ، و FreeBSD 13. في كل حالة ، قمت بالتحقق باستخدام مصحح أخطاء من أننا نجري استدعاءات النظام المناسبة. لسوء الحظ ، لم أتمكن من الحصول على الكود للبناء على OpenBSD 6.5 أو NetBSD 8.1 أو Solaris 10 بسبب بعض مشكلات libevent غير ذات الصلة ، لكنني لست متأكدًا من أن هذه الأنظمة الأساسية مدعومة لـ libtransmission بعد الآن. في أي حال ، يجب ألا يؤثر هذا التغيير على تلك الأنظمة الأساسية.

ما يزال أن أفعل:

  • اختبر على نواة Windows أقدم. تحتاج إلى تكوين بيئة تطوير آلة افتراضية لذلك.
  • اختبر نسخة الحجم المتقاطعة (لأن هذا ما نهتم به). لست متأكدًا من كيفية القيام بذلك كاختبار آلي.
  • اختبار الملف tr_sys_path_copy () لملف كبير بشكل معقول (> 100 جيجا بايت). ربما لا يمكن القيام به كاختبار آلي.
  • اختبر في الموقع بدلاً من مجرد اختبار tr_sys_path_copy () بمعزل عن غيرها.
  • استبدل أحد خوادم التورنت الصغيرة الخاصة بي بهذا الرمز لفترة من الوقت ، وانظر كيف يتصرف في العالم الحقيقي.

نرحب بالتعليقات.

+1 لجعل نقل البيانات غير متزامن. يؤدي نقل ملفات التورنت الكبيرة بين أنظمة الملفات إلى قفل التطبيق بالكامل .

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات