Ember.js: [2.15.0] - Ember membangun kesalahan memori saat menggunakan alat CI

Dibuat pada 7 Sep 2017  ·  23Komentar  ·  Sumber: emberjs/ember.js

Transpiling babel paralel diperkenalkan di bara 2.15. (https://github.com/babel/broccoli-babel-transpiler#number-of-jobs)

Secara default, brokoli-babel-transpiler menggunakan sumber daya sistem (cpus) untuk menentukan jumlah pekerjaan yang dapat dijalankan secara paralel.

Sebagian besar alat CI modern menggunakan buruh pelabuhan untuk membantu mengisolasi build dari build lain yang berjalan di server tertentu. Ini memungkinkan mereka menggunakan VM besar untuk menjalankan banyak build yang sebagian besar terisolasi satu sama lain. Misalnya, VM yang dijalankan Circle CI biasanya memiliki 36 inti CPU... Tetapi build itu sendiri terbatas pada dua.

Masalah muncul ketika mencoba menggunakan cara tradisional untuk menentukan sumber daya apa yang tersedia untuk program. Misalnya, untuk menentukan jumlah CPU yang menggunakan node, Anda dapat melakukan node -e "console.log(require('os').cpus().length);" . Namun, informasi ini sebenarnya melaporkan sumber daya instans, bukan sumber daya terbatas yang tersedia untuk wadah buruh pelabuhan. Menghasilkan apa pun yang berjalan berpikir itu mendapat akses ke 36 core tetapi sebenarnya hanya memiliki dua.

Saya telah membuat contoh repo:
https://github.com/mwisner/ember-circleci-example di mana Anda dapat melihat riwayat build yang lulus dan gagal (https://circleci.com/gh/mwisner/ember-circleci-example) (https:// travis-ci.org/mwisner/ember-circleci-example/builds) (Saya belum memperbaiki travis build.)

Alat CI yang teruji
-- Lingkari CI 2.0
-- Lingkari CI 1.0
-- Travis CI (Gagal dengan default yang disediakan Travis CI)

Dokumen pekerjaan paralel: https://github.com/babel/broccoli-babel-transpiler#number -of-jobs

Ketika kesalahan muncul, mereka terlihat seperti output di bawah ini. Namun dalam banyak situasi (seperti travis CI) waktu habis setelah 10 menit tanpa informasi apa pun)

#!/bin/bash -eo pipefail
ember test
Could not start watchman
Visit https://ember-cli.com/user-guide/#watchman for more info.
Building
'instrument' is imported from external module 'ember-data/-debug' but never used
/usr/local/bin/node[1116]: ../src/node_file.cc:598:void node::InternalModuleReadFile(const v8::FunctionCallbackInfo<v8::Value>&): Assertion `(numchars) >= (0)' failed.
fs.js:682
  var r = binding.read(fd, buffer, offset, length, position);
                  ^

Error: ENOMEM: not enough memory, read
    at Object.fs.readSync (fs.js:682:19)
    at tryReadSync (fs.js:480:20)
    at Object.fs.readFileSync (fs.js:509:19)
    at Object.Module._extensions..js (module.js:579:20)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at /home/circleci/app/node_modules/esutils/lib/utils.js:31:23
fs.js:682
  var r = binding.read(fd, buffer, offset, length, position);
                  ^

Error: ENOMEM: not enough memory, read
    at Object.fs.readSync (fs.js:682:19)
    at tryReadSync (fs.js:480:20)
    at Object.fs.readFileSync (fs.js:509:19)
    at Object.Module._extensions..js (module.js:579:20)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/home/circleci/app/node_modules/ember-power-select/node_modules/babel-core/lib/transformation/transformers/index.js:43:22)
fs.js:682
  var r = binding.read(fd, buffer, offset, length, position);
                  ^

Error: ENOMEM: not enough memory, read
    at Object.fs.readSync (fs.js:682:19)
    at tryReadSync (fs.js:480:20)
    at Object.fs.readFileSync (fs.js:509:19)
    at Object.Module._extensions..js (module.js:579:20)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/home/circleci/app/node_modules/debug/src/node.js:14:28)
 1: node::Abort() [/usr/local/bin/node]
 2: node::Assert(char const* const (*) [4]) [/usr/local/bin/node]
 3: 0x12e49fa [/usr/local/bin/node]
 4: v8::internal::FunctionCallbackArguments::Call(void (*)(v8::FunctionCallbackInfo<v8::Value> const&)) [/usr/local/bin/node]
 5: 0xb45e2c [/usr/local/bin/node]
 6: v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
 7: 0x1cbf812040c7
fs.js:682
  var r = binding.read(fd, buffer, offset, length, position);
                  ^

Error: ENOMEM: not enough memory, read
    at Object.fs.readSync (fs.js:682:19)
    at tryReadSync (fs.js:480:20)
    at Object.fs.readFileSync (fs.js:509:19)
    at Object.Module._extensions..js (module.js:579:20)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/home/circleci/app/node_modules/debug/src/node.js:14:28)
fs.js:682
  var r = binding.read(fd, buffer, offset, length, position);
                  ^

Error: ENOMEM: not enough memory, read
    at Object.fs.readSync (fs.js:682:19)
    at tryReadSync (fs.js:480:20)
    at Object.fs.readFileSync (fs.js:509:19)
    at Object.Module._extensions..js (module.js:579:20)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/home/circleci/app/node_modules/regenerator/node_modules/ast-types/lib/node-path.js:6:12)
cleaning up
cleaning up...
Build failed.
The Broccoli Plugin: [BroccoliMergeTrees: Addon#treeFor (ember-concurrency - addon)] failed with:
Error: Worker terminated unexpectedly
    at ChildProcess.<anonymous> (/home/circleci/app/node_modules/workerpool/lib/WorkerHandler.js:177:17)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:194:7)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:215:12)

The broccoli plugin was instantiated at: 
    at BroccoliMergeTrees.Plugin (/home/circleci/app/node_modules/broccoli-plugin/index.js:7:31)
    at new BroccoliMergeTrees (/home/circleci/app/node_modules/broccoli-merge-trees/index.js:16:10)
    at Function.BroccoliMergeTrees [as _upstreamMergeTrees] (/home/circleci/app/node_modules/broccoli-merge-trees/index.js:10:53)
    at mergeTrees (/home/circleci/app/node_modules/ember-cli/lib/broccoli/merge-trees.js:85:33)
    at Class.treeFor (/home/circleci/app/node_modules/ember-cli/lib/models/addon.js:526:30)
    at addons.reduce (/home/circleci/app/node_modules/ember-cli/lib/models/addon.js:383:26)
    at Array.reduce (native)
    at Class.eachAddonInvoke (/home/circleci/app/node_modules/ember-cli/lib/models/addon.js:380:24)
    at Class.treeFor (/home/circleci/app/node_modules/ember-cli/lib/models/addon.js:515:22)
    at project.addons.reduce (/home/circleci/app/node_modules/ember-cli/lib/broccoli/ember-app.js:559:25)


Exited with code 1

Solusi "Solusi", yang disediakan oleh @rwjblue , adalah untuk secara khusus menentukan jumlah pekerjaan yang ingin Anda gunakan untuk transpiling paralel dengan memanfaatkan JOBS ENV var. (https://github.com/mwisner/ember-circleci-example/blob/09c63e11c34d4cdfe602b63166b71e6f31e30f3c/.circleci/config.yml#L42)

Has Reproduction

Komentar yang paling membantu

Saya mengobrol dengan @mwisner dan @kiwiupover sedikit tentang ini selama akhir pekan dan kami menemukan bahwa itu ada hubungannya dengan paralelisme baru yang ditambahkan ke brokoli-babel-transpiler. Ini default untuk memparalelkan ke jumlah CPU yang ada saat ini. Sayangnya, di CircleCI ini ditampilkan sebagai 36 CPU tetapi pekerjaan itu sendiri terbatas pada 2 proses bersamaan (dan juga terbatas pada RAM yang tersedia).

Perbaikan di sini adalah mengatur variabel lingkungan JOBS ke 1 untuk menonaktifkan paralelisme pada CI.

Semua 23 komentar

Tampaknya ada beberapa orang yang memiliki tes karma yang berhasil dengan langkah ini:

https://discuss.circleci.com/t/running-browser-tests/10998/9

Setelah beberapa jam terakhir, saya belum berhasil menjalankan ini dengan sukses, tetapi saya cukup yakin ini bukan ember.js.... Penutupan untuk saat ini.

Saya mengalami masalah yang sama dan tidak dapat menyelesaikannya.

Saya mengobrol dengan @mwisner dan @kiwiupover sedikit tentang ini selama akhir pekan dan kami menemukan bahwa itu ada hubungannya dengan paralelisme baru yang ditambahkan ke brokoli-babel-transpiler. Ini default untuk memparalelkan ke jumlah CPU yang ada saat ini. Sayangnya, di CircleCI ini ditampilkan sebagai 36 CPU tetapi pekerjaan itu sendiri terbatas pada 2 proses bersamaan (dan juga terbatas pada RAM yang tersedia).

Perbaikan di sini adalah mengatur variabel lingkungan JOBS ke 1 untuk menonaktifkan paralelisme pada CI.

@rwjblue terima kasih untuk konteksnya di sini!

Bahkan dengan paralelisme Circle, saya akan berpikir (karena mereka dipecah menjadi wadah) bahwa JOBS akan selalu harus 1, kalau begitu. Jadi oleh...

pada dasarnya menonaktifkan paralelisme pada CI

...Saya berasumsi bahwa Anda bermaksud menonaktifkan paralelisme brokoli-babel-transpiler dan bukan paralelisme kemas Circle. Apakah itu benar?

@eric-hu apakah ini juga tampak seperti bacaan yang benar bagi Anda? Apakah ini sesuatu yang harus kita harapkan untuk diperbaiki dari Circle sehingga CPU yang benar-benar tersedia dalam pekerjaan ditampilkan? Apakah ini mencegah paralelisme apa pun di pihak Circle (dengan membagi tes dengan sesuatu seperti ember-exam misalnya)?

Saya tidak yakin apakah kita dapat mengharapkan perbaikan dari circleci sendiri ... Saya tidak super 100% tapi saya pikir ini lebih merupakan masalah Docker daripada masalah lingkaran secara khusus. Atau mungkin masalah Node + Docker yang tidak dapat secara akurat mendeteksi batasan cpu/mem yang diberlakukan oleh wadah buruh pelabuhan.

Saya telah membuat repo ini untuk tujuan eksperimen: https://github.com/mwisner/ember-circleci-example.

Ini termasuk circleci 2.0 (bekerja dengan solusi JOBS=1 yang disediakan oleh @rwjblue) (https://github.com/mwisner/ember-circleci-example/blob/master/.circleci/config.yml)

Bersama dengan pembuatan lingkaran publik: https://circleci.com/gh/mwisner/ember-circleci-example/83

Namun saya juga telah menambahkan repo ke travis ci, yang juga menggunakan Docker untuk build, saya belum memperbaiki file konfigurasi travis tetapi Anda dapat melihat build travis gagal dengan konfigurasi travis yang disediakan (https://travis- ci.org/mwisner/ember-circleci-example/builds)

Terima kasih @mwisner. Apakah saya benar dalam berpikir bahwa JOBS=1 tidak _not_ berarti kita tidak dapat memparalelkan build itu sendiri?

@JoshSmith Ya jika saya mengerti dengan benar itu untuk menonaktifkan paralelisme dalam brokoli-babel-transpiler. Bukan lingkaran itu sendiri. Jadi secara teori menggunakan paralelisme circleci + jobs=1 akan baik-baik saja?

Tetapi secara pribadi, saya belum bereksperimen dengan menggunakan fungsionalitas paralelisme circleci. Jadi saya tidak 100% yakin seperti apa file konfigurasi itu nantinya.

Masuk akal! Saya ingin memastikan bahwa saya baru saja menarik garis yang jelas antara apa yang tampak seperti dua penggunaan "paralelisme" yang berbeda di sini, jadi saya pikir saya akhirnya berada di halaman yang sama.

Saya perhatikan Anda mengatur JOBS=1 secara manual di konfigurasi sebelum ember test , tetapi sepertinya itu dapat diatur pada level ENV var dalam Circle, mungkin tanpa masalah?

Ini juga tidak spesifik untuk pengujian. Masalah OOM disebabkan selama fase build uji ember. Saya telah menguji hanya menjalankan ember build juga dengan hasil OOM yang sama.

@JoshSmith Saya percaya pengaturan JOBS=1 di level env var akan berfungsi juga, tetapi saya belum mengonfirmasi.

Saya perhatikan ada pola untuk mengatur env vars untuk perintah ember cli untuk beberapa tambahan:

https://github.com/ember-cli/broccoli-viz#usage
https://github.com/kategengler/ember-cli-code-coverage#usage

Jadi saya baru saja keluar dari pola penggunaan itu.

Tanpa mengetahui _anything_ tentang bagaimana sebenarnya broccoli-babel-transpiler bekerja, sulit bagi saya untuk mengatakan apakah Circle (atau Docker, atau siapa pun) dapat memberikan perbaikan untuk itu. _Perasaan_ awam saya – tidak berpikir – seputar ini adalah jika transpiler dapat mengambil instruksi eksplisit tentang berapa banyak inti yang tersedia, maka kita mungkin dapat menghindari masalah inferensi murni di sini. Sekali lagi, ini berasal dari tempat ketidaktahuan yang mendalam.

Hanya untuk memperbarui, saya dapat menjalankan build ini dengan sukses dengan JOBS disetel ke 1 di pengaturan lingkungan Circle. Sekali lagi terima kasih @rwjblue , @mwisner , dan @eric-hu.

Saya baru saja mengalami masalah yang sama di CircleCI, dan JOBS=1 juga memperbaikinya untuk saya, terima kasih semuanya :v:

@eric-hu apakah ini juga tampak seperti bacaan yang benar bagi Anda? Apakah ini sesuatu yang harus kita harapkan untuk diperbaiki dari Circle sehingga CPU yang benar-benar tersedia dalam pekerjaan ditampilkan? Apakah ini mencegah paralelisme apa pun di pihak Circle (dengan membagi tes dengan sesuatu seperti ujian ember misalnya)?

@JoshSmith ada dua konsep paralelisme yang perlu diingat untuk CircleCI 2.0:

A. Paralelisme per-perintah, terbatas pada jumlah inti yang tersedia untuk grup penampung. Secara default, setiap grup penampung dialokasikan 2 bagian CPU, yang menjamin mereka mendapatkan 2 inti CPU. Ada fitur Sumber Daya yang Dapat Dikonfigurasi premium yang memungkinkan Anda memilih bagian yang lebih besar/lebih kecil (1, 4, 8 dari atas kepala saya).

B. Paralelisme CircleCI, yang dapat Anda anggap sebagai "berapa banyak mesin [1] yang ingin saya bagi?". Ini berguna untuk isolasi pengujian, ketika Anda mungkin ingin menjalankan 2 pengujian secara bersamaan dan keduanya menulis ke database. Ini kurang berguna untuk, katakanlah, memindahkan aset Anda ; Anda mungkin ingin semua pengujian Anda berjalan dengan aset yang ditranspilasikan.

Mengenai A: karena Anda memiliki 2 core yang dijamin tersedia secara default, Anda mungkin dapat menjalankan perintah yang Anda inginkan dengan JOBS=2. Ini mungkin mempercepat eksekusi, tetapi saya belum memeriksa apakah itu berfungsi.

Mengenai B: bahkan dengan JOBS=1, Anda masih dapat menggunakan paralelisme CircleCI untuk mempercepat rangkaian pengujian Anda.

Mengenai "siapa yang harus memperbaiki ini", saya telah melihat ini sebagai masalah lama dengan beberapa alat containerization. Alat containerization CircleCI 2.0 dan 1.0 --Docker dan LXC masing-masing-- membocorkan informasi tentang sistem host untuk banyak perintah Linux umum, seperti yang digunakan untuk memeriksa berapa banyak inti yang tersedia. Sudah seperti ini selama beberapa tahun, saya pikir jika ada perbaikan sederhana itu akan diselesaikan sekarang. Lebih rumit lagi, CircleCI mengubah model ketersediaan inti CPU dari 1.0 menjadi 2.0. Di 1.0, Anda mendapatkan jumlah inti yang tetap untuk suatu pekerjaan. Di 2.0, Anda mendapatkan pembagian CPU yang ditetapkan untuk menjamin jumlah inti minimum Anda. Jika Anda menggunakan host yang sepenuhnya digunakan, Anda akan mendapatkan setidaknya banyak inti. Jika Anda menjalankan host yang kurang dimanfaatkan, Anda akan memiliki lebih banyak inti yang tersedia untuk Anda. Alat seperti broccoli-babel-transpiler cenderung menetapkan jumlah inti yang akan mereka gunakan hanya sekali, dan sumber daya yang tersedia dapat berubah selama masa eksekusi program. Yang terbaik adalah membuat kode keras skrip CI Anda untuk menggunakan sumber daya yang dijamin tersedia.

[1] Kode Anda mungkin tidak berjalan pada mesin N untuk paralelisme N. Tetapi Anda dapat memikirkannya seperti ini, karena mereka secara efektif terisolasi satu sama lain.

Baru saja mencoba JOBS=2 di aplikasi saya dan pembangunannya juga berhasil. Haruskah itu menjadi saran kanonik di sini?

Tidak ada perbedaan waktu yang mencolok antara nilai-nilai itu dalam sampel kecil saya FWIW.

@rwjblue Saya tahu Anda merekomendasikan untuk mengalami masalah ini di repo ember-cli. Namun saya membuka masalah ini ketika saya pertama kali menemukan masalah dan sepertinya itu ditemukan sebelum saya dapat membuka yang lain di ember-cli repo... Apakah Anda ingin saya membuka masalah lain di sana dan hanya merujuk percakapan ini? Tahu sih cara mudah memindahkannya?

Saya membuka kembali masalah ini karena setelah melakukan beberapa pengujian tambahan, konfigurasi travisci.yml yang disediakan yang dikirimkan dengan ember juga mengalami masalah ini.

Meskipun saya mengerti bahwa ember tidak mendukung lingkaran, saya pikir akan lebih baik untuk setidaknya memperbaiki masalah di file travisci.yml yang dikirimkan.

Saya juga telah memperbarui judul dan deskripsi untuk membuatnya sedikit lebih umum dan tidak dicakup secara khusus untuk circleCI

@eric-hu banyak terima kasih atas saran terperinci di sini. Sangat membantu masyarakat untuk memahami apa yang terjadi secara detail. Akan sangat bagus untuk melihat contoh kanonik dalam dokumentasi berdasarkan kerangka kerja, meskipun saya memahami dan menghargai waktu yang diperlukan.

@bgentry terima kasih telah melaporkan perbedaan waktu. Saya berharap itu akan mempercepat waktu pembuatan. Saya akan menetapkan JOBS=2 , juga, tetapi saya sedikit kecewa tentang ini karena waktu pembuatan saya sejauh ini merupakan penghalang terbesar saya dalam mempercepat pekerjaan Circle.

oh wow, saya senang akhirnya menemukan percakapan ini, karena ini juga terjadi pada saya. Saya tidak tahu apa yang harus dicari pada awalnya karena npm test menghabiskan waktu untuk saya di Travis, tanpa umpan balik. Tidak sampai saya mencoba mengesampingkan batas waktu (yang biasanya Anda harus tulis untuk mendukung untuk melakukannya) saya mendapat ENOMEM , yang akhirnya membawa saya ke sini.

Mengubah ke JOBS=2 npm test telah menyebabkan build saya lolos lagi (atau setidaknya gagal karena alasan yang tepat ) jadi terima kasih semuanya!

Mungkin ini hanya terjadi pada saya di Travis karena aplikasi memiliki dependensi yang berat, tetapi sulit untuk di-debug dan saya mengabaikannya untuk waktu yang lama, jadi sepertinya layak untuk mempertimbangkan bagaimana menangani ini di cetak biru Ember CLI atau alamat lainnya dia.

Dalam pengujian saya, proyek ember default di luar kotak tanpa perubahan apa pun berjalan dengan baik, pengenalan banyak dependensi akhirnya menyebabkan kesalahan.

Saya tidak yakin apa yang dianggap sebagai 'banyak' dependensi dalam proyek bara. Tetapi dengan travis menjadi cara de-facto untuk melakukan CI dengan add-on ember, saya pikir ketika orang-orang mulai memutakhirkan / membuat add-on baru, orang-orang akan melihat ini lebih dan lebih.

Saya baru-baru ini mulai bekerja untuk memutakhirkan semua dependensi untuk proyek menu ember-burger dan saya mendapatkan kesalahan ini.
Contoh:
https://travis-ci.org/offirgolan/ember-burger-menu/builds/275031562?utm_source=github_status&utm_medium=notification
https://github.com/offirgolan/ember-burger-menu/pull/95

Oh! Terima kasih @mwisner telah memposting masalah ini dan @rwjblue untuk solusi sementara! Saya hanya menghabiskan beberapa jam mencoba memahami mengapa build saya gagal.. Menyetel JOBS ke 1 berhasil

Menutup sebagai JOBS=1 telah diperbarui sebagai default di ember-cli beberapa waktu lalu. Mohon maaf atas kendalanya...

Saya hanya perlu menambahkan JOBS=1 untuk memperbaiki masalah ini pada 3.16.0. Apakah ada regresi?

Apakah halaman ini membantu?
0 / 5 - 0 peringkat