Как да се справя с много големи качвания на файлове в уеб сървър на Erlang?

И така, да речем, че пиша уеб сървър и искам да поддържам "много големи" качвания на файлове. Нека допълнително приемем, че искам да направя това чрез стандартния MIME тип multipart/form-data. Трябва да кажа, че използвам erlang и че планирам да събирам http пакети, докато се връщат от erlang:decode_packet/2, но не искам всъщност да събирам тялото на заявката, докато манипулаторът на http заявки не намери място за каченото съдържание. Трябва ли аз

а) продължете и съберете тялото така или иначе, като игнорирате възможността то да е много много голямо и по този начин евентуално да срине сървъра поради изчерпване на паметта му?

б) да се въздържат от получаване в сокета на всяко (евентуално несъществуващо) тяло на заявка, докато заглавките не бъдат обработени?

в) направи нещо друго?

Пример за отговор c може да бъде: създаване на друг процес за събиране и запис на качено съдържание на временно местоположение (за да се сведе до минимум използването на памет), като едновременно с това се предоставя това местоположение на манипулатора на http заявки за бъдеща обработка. Но просто не знам - тук има ли стандартна техника?


person Aoriste    schedule 04.03.2010    source източник
comment
Е, консенсусът изглежда е, че стандартният начин е да се направи това, което предложих за опция c. Все пак смятам, че трябва да има по-добър начин - притеснява ме неудобството на временните файлове - те изискват допълнителни erlang портове, за да бъдат отворени (повече от веднъж, ако планирам да прочета файла обратно в даден момент) и те разделят между два или повече процеса това, което бих искал да се обработва от единия. Това обаче е, което планирах да направя - надявах се, че някой може да прави нещата по различен начин.   -  person Aoriste    schedule 05.03.2010
comment
Трябва да съхраните данните. На практика това се прави в паметта или на устройство за съхранение. Вашият въпрос казва, че паметта не е опция; вашият коментар казва, че и вие не обичате да го съхранявате на устройство. Единственият оставащ вариант е окултизмът...   -  person Zed    schedule 05.03.2010


Отговори (3)


Според мен вариант b очевидно е по-добрият.

През периода от време, в който не четете сокета, TCP кодът ще продължи да буферира входящите данни в ядрото. Докато го прави, той ще рекламира все по-малък и по-малък размер на TCP прозореца на HTTP сървъра, докато в крайна сметка (когато TCP приемните буфери в ядрото са пълни), TCP прозорецът ще се затвори.

С други думи, като не четете сокета, вие позволявате на контрола на TCP потока да си свърши работата.

person Bruno Rijsman    schedule 06.03.2010
comment
Тайно търсех оправдание да направя b, благодаря, че помогнахте да го предоставим. Според мен има по-добър смисъл от поддръжка на код, но това не ми беше достатъчно, за да го внедря. - person Aoriste; 07.03.2010

В моята реализация използвам вашия пример за отговор c - чета от сокет парче по парче и съхранявам парчета във временен файл. Също така, afaik yaws използва подобна техника - можете да я видите на yaws/src/yaws_multipart.erl

person W55tKQbuRu28Q4xv    schedule 04.03.2010

Съхраняването във временен файл също е начинът, по който PHP прави нещата, така че е изпитан начин. Можете да преброите получените байтове и да прекъснете връзката, ако достигне размер, който няма смисъл.

person Tor Valamo    schedule 04.03.2010