2016-11-24 27 views
1

更新: getSections関数を手動で実行すると、正常に動作しているようです。エラーの原因となるパラメータをプリントアウトすると、それは別のセットが...同じ接続でもmongodbの接続に失敗しました。


私はその中に、いくつかの異なる機能を呼び出すupdateCurrentTerm()関数を持っている、すべての更新異なるコレクションは、すべての時間です同じデータベースのMONGOURL'mongodb://localhost:27017/'で、term'4650'ある

MongoClient.connect(MONGOURL + term, (err, db) => { 

:これらのそれぞれは、次のような、まったく同じ方法で、DBへの接続を行います。ただし、接続はgetSchoolsgetSubjectsgetCoursesでは有効ですが、getSectionsでは機能していないようです。

TypeError: Cannot read property 'collection' of null 
    at /Users/Joon/sans/app.js:129:26 
    at connectCallback (/Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:315:5) 
    at /Users/Joon/sans/node_modules/mongodb/lib/mongo_client.js:222:11 
    at _combinedTickCallback (internal/process/next_tick.js:67:7) 
    at process._tickCallback (internal/process/next_tick.js:98:9) 

が、私はさらに調査:nullがERRパラメータがnullではなかったことを意味しているMongoClient.connectコールバックのDBパラメータここで私は取得しています完全なエラーです。エラーパラメータには次の情報が含まれています:

{ MongoError: failed to connect to server [localhost:27017] on first connect 
    at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/topologies/server.js:313:35) 
    at emitOne (events.js:96:13) 
    at emit (events.js:188:7) 
    at .<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/pool.js:271:12) 
    at g (events.js:286:16) 
    at emitTwo (events.js:106:13) 
    at emit (events.js:191:7) 
    at Socket.<anonymous> (/Users/Joon/sans/node_modules/mongodb-core/lib/connection/connection.js:165:49) 
    at Socket.g (events.js:286:16) 
    at emitOne (events.js:96:13) 
    name: 'MongoError', 
    message: 'failed to connect to server [localhost:27017] on first connect' } 

ご協力いただければ幸いです。ありがとうございました!


app.js

import { MongoClient } from 'mongodb'; 
import request from 'request-json'; 
import { EventEmitter } from 'events'; 

const API = request.createClient('http://www.northwestern.edu/class-descriptions/'); 
const MONGOURL = 'mongodb://localhost:27017/'; 
const EVENT = new EventEmitter(); 


const makeRequest = (query, type, callback) => { 
    // Possible types: 
    // terms 
    // schools 
    // subjects 
    // courses 
    // sections 
    // details 

    // Prepare query with correct ending 
    if (type === 'terms') { 
     query = 'index-v2.json'; 
    } else if (type === 'details') { 
     query += '-v2.json'; 
    } else { 
     query += '/index-v2.json'; 
    } 

    API.get(query, (err, response, body) => { 
     if (err) { 
      console.log(err); 

      callback(null, err); 
     } else { 
      // Parse out last non-data term 
      const last = body[body.length - 1]; 
      const lastKeys = Object.keys(last); 
      if (lastKeys.length === 1 && lastKeys[0] === 'ignore') { 
       body.pop(); 
      } 

      callback(body, null); 
     } 
    }); 
} 

const getTerms = (callback) => { 
    // TODO: Refactor to insert only if new term 
    MongoClient.connect(MONGOURL + 'terms', (err, db) => { 
     const coll = db.collection('data'); 
     coll.remove(); // Start clean 
     makeRequest('', 'terms', (data, err) => { 
      if (!err) { 
       coll.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getSchools = (term, callback) => { 
    // term is the term id (not the mongodb _id) 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const schools = db.collection('schools'); 
     makeRequest(term, 'schools', (data, err) => { 
      if (!err) { 
       schools.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getSubjects = (term, school, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const subjects = db.collection('subjects'); 

     const query = term + '/' + school; 
     makeRequest(query, 'subjects', (data, err) => { 
      if (!err) { 
       subjects.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getCourses = (term, school, subject, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    // subject is the subject abbv 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const courses = db.collection('courses'); 

     const query = term + '/' + school + '/' + subject; 
     makeRequest(query, 'courses', (data, err) => { 
      if (!err) { 
       courses.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getSections = (term, school, subject, course, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    // subject is the subject abbv 
    // course is the course abbv 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     console.log(err); 
     const sections = db.collection('sections'); 

     const query = term + '/' + school + '/' + subject + '/' + course; 
     makeRequest(query, 'sections', (data, err) => { 
      if (!err) { 
       sections.insertMany(data, (err, result) => { 
        db.close(); 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const getDetails = (term, school, subject, course, section, callback) => { 
    // term is the term id (not the mongodb _id) 
    // school is the school id (not the mongodb _id) 
    // subject is the subject abbv 
    // course is the course abbv 
    // section is the section id (not the mongodb _id) 
    MongoClient.connect(MONGOURL + term, (err, db) => { 
     const details = db.collection('details'); 

     const query = term + '/' + school + '/' + subject + '/' + course + '/' + section; 
     makeRequest(query, 'details', (data, err) => { 
      if (!err) { 
       details.insertMany(data, (err, result) => { 
        callback(data); 
       }); 
      } else { 
       db.close(); 
      } 
     }); 
    }); 
}; 

const updateCurrentTerm =() => { 
    MongoClient.connect(MONGOURL + 'terms', (err, db) => { 
     const terms = db.collection('data'); 
     // Find term with max id (not mongodb _id) 
     terms.find().sort({id:-1}).limit(1).next((err, doc) => { 
      EVENT.emit('maxTerm', doc.id); 
      db.close(); 
     }); 
    }); 

    EVENT.on('maxTerm', (term) => { 
     MongoClient.connect(MONGOURL + term, (err, db) => { 
      db.collection('schools').remove(); 
      db.collection('subjects').remove(); 
      db.collection('courses').remove(); 
      db.collection('sections').remove(); 
      db.collection('details').remove(); 
      db.close(); 
      EVENT.emit('clean', term); 
     }); 
    }); 

    EVENT.on('clean', (term) => { 
     getSchools(term, (data) => { 
      EVENT.emit('updatedSchools', term, data); 
     }); 
    }); 

    EVENT.on('updatedSchools', (term, data) => { 
     data.forEach((school) => { 
      getSubjects(term, school.id, (newData) => { 
       EVENT.emit('updatedSubjects', term, school.id, newData); 
      }); 
     }); 
    }); 

    EVENT.on('updatedSubjects', (term, school, data) => { 
     data.forEach((subject) => { 
      getCourses(term, school, subject.abbv, (newData) => { 
       EVENT.emit('updatedCourses', term, school, subject.abbv, newData); 
      }); 
     }); 
    }); 

    EVENT.on('updatedCourses', (term, school, subject, data) => { 
     data.forEach((course) => { 
      getSections(term, school, subject, course.abbv, (newData) => { 
       EVENT.emit('updatedSections', term, school, subject, course.abbv, newData); 
      }); 
     }); 
    }); 
} 

updateCurrentTerm(); 
+0

mongodログも共有できますか? –

+0

mongodを起動し、app.jsを一度実行したログがあります:https://gist.github.com/Joonpark13/e815c260820db9343f3c7f0909d39c2c –

+0

'getSchools'、' getSubjects'、 'getCourses'、' getSections'の 'term'をチェックしましたか? 'when updateCurrentTerm()'?それは同じでなければなりません、そうですか? –

答えて

1

クエリを実行しているたびに、新しいインスタンスを作成しているし、それはあなたのmongodにあまりにも多くの接続です!これは、各インスタンスが最低1つの接続(デフォルトでは10)を作成して保持し、Java GCがMongoインスタンスをクリーンアップした場合、またはclose()を呼び出す場合にのみ、これらの接続が削除されるため動作しません。

Mongoへの新しい接続の作成は非常にコストがかかり、mongodのパフォーマンスも低下します。 1つのMongoインスタンスを作成し、できるだけ長く維持してください!遅れて作成されたインスタンスを返す静的メソッドgetInstance()を使用してMongoFactoryを実装すると、そのトリックはうまくいくでしょう。

+0

私はコードをリファクタリングして、接続の数をはるかに少なくできました。現在はほとんどエラーが発生していないようです。ありがとうございました! –

関連する問題