#include "Weather.h" #ifdef UTIL_DEBUG extern UTIL::MemoryManager g_clsCMemory; extern UTIL::MemoryManager g_clsCppMemory; UTIL::MemoryManager * g_ptrMemory[] = {&g_clsCMemory, &g_clsCppMemory}; #endif bool g_blnProgramShouldStop = false; int main(int intArgc, char ** ptrArgv) { UTIL::D2::g_stuWrap = UTIL::D2::Box(0.0f, 360.0f, -90.0f, 90.0f); UTIL::Socket clsMutexSocket; UTIL::Config clsConfig; UTIL::File clsOutStd; UTIL::File clsOutErr; char * ptrRequiredFields[4] = { "mutex_port", "host_file", "product_file", "basedir", }; if ( intArgc < 2 ) { fprintf(stderr, "The configuration file must be supplied at the command line\n"); return -1; } else if ( clsConfig.InitProgram(ptrArgv[1], (const char **)(&(ptrRequiredFields[0])), 4, &clsOutStd, "std_log_file", &clsOutErr, "err_log_file", &clsMutexSocket, "mutex_port") == false ) { return -1; } // // Initialize logging // clsOutErr.SetDupOut(&clsOutStd); UTIL::Log clsLogStd(&clsOutStd, UTIL::Log::DATE | UTIL::Log::TIME | UTIL::Log::MUTEX, NULL, "\n"); UTIL::Log clsLogErr(&clsOutErr, UTIL::Log::DATE | UTIL::Log::TIME | UTIL::Log::MUTEX, NULL, "\n"); UTIL::LogArchive clsArchive("WEATHER DATA", NULL, clsConfig["status_email_address"], clsConfig["std_log_file"], clsConfig["err_log_file"]); time_t intTime = time(NULL); clsOutStd.Printf("%s\r\nConfiguration file contents:\r\n----------------------------\r\n", ctime(&intTime)); clsConfig.Dump(&clsOutStd); clsOutStd.Write("----------------------------\r\n"); // // Add default configuration options // if ( clsConfig["max_threads"] == NULL ) clsConfig.AddValue("max_threads", "8"); // // Read the group and host files // Weather::HostList clsHosts; Weather::GroupList clsGroups; if ( Weather::Host::Read(clsConfig["host_file"], clsHosts) == false || Weather::Group::Read(clsConfig["product_file"], clsGroups) == false ) { clsLogErr.Printf("Could not read host and/or product files (host file: %s, product file: %s)", clsConfig["host_file"], clsConfig["product_file"]); return -1; } // // Log the results // clsLogStd.Printf("Read %u hosts from %s", clsHosts.size(), clsConfig["host_file"]); clsLogStd.Printf("Read %u groups from %s", clsGroups.size(), clsConfig["product_file"]); // // Perform sanity checks on the data // bool blnResult = true; Weather::GroupList::iterator ptrGroupStart; Weather::GroupList::iterator ptrGroupEnd = clsGroups.end(); for (ptrGroupStart = clsGroups.begin(); ptrGroupStart != ptrGroupEnd; ptrGroupStart++) { if ( (*ptrGroupStart)->Init(clsConfig["basedir"], true, clsLogErr) == false ) { blnResult = false; } } if ( blnResult == false ) return -1; // // Object initialization // UTIL::Mutex clsMutex(true); if ( clsMutex.Create() == false ) { clsLogErr.Printf("Could not create a mutex"); return -1; } else if ( UTIL::Socket::Initialize() == false ) { clsLogErr.Printf("Could not initialize socket library"); return -1; } //#ifndef WIN32 // g_ptrConfigData = ptrConfig; // sigset(SIGINT, CHOP_SignalHandler); // sigset(SIGPIPE, CHOP_SignalHandler); // sigset(SIGKILL, CHOP_SignalHandler); // sigset(SIGTERM, CHOP_SignalHandler); //#endif // // Check hosts for availability of files // unsigned int uintMaxThreads = (unsigned int)(clsConfig.Integer("max_threads")); clsLogStd.Printf("Weather downloader starting --- max concurrent threads: %i", uintMaxThreads); Weather::HostList::iterator ptrHostStart; Weather::HostList::iterator ptrHostEnd = clsHosts.end(); for (ptrHostStart = clsHosts.begin(); ptrHostStart != ptrHostEnd; ptrHostStart++) { Weather::Host & clsHost = *(*ptrHostStart); if ( clsHost.Connect() == false ) { clsLogErr.Printf("Could not connect to host %s", clsHost.m_ptrName); continue; } clsHost.CheckVersions(clsGroups, clsLogStd); clsHost.Disconnect(); } // // Start threads to download each file // unsigned int uintCurrentThreads = 0; Weather::Host::ThreadObjects * ptrThread; Weather::HostList::iterator ptrHostIndex = clsHosts.begin(); while ( ptrHostIndex != ptrHostEnd || uintCurrentThreads != 0 ) { bool blnActive = false; for (ptrHostStart = clsHosts.begin(); ptrHostStart != ptrHostEnd; ptrHostStart++) { if ( (*ptrHostStart)->m_enmStatus == Weather::Host::STATUS_COMPLETED_THREAD ) { (*ptrHostStart)->m_enmStatus = Weather::Host::STATUS_FINISHED; clsLogStd.Printf("Thread ended for %s (%u threads running)", (*ptrHostStart)->m_ptrName, --uintCurrentThreads); } } if ( g_blnProgramShouldStop == false ) { // // See if we should start more threads // while ( uintCurrentThreads < uintMaxThreads && ptrHostIndex != ptrHostEnd ) { Weather::Host & clsHost = *(*ptrHostIndex); if ( clsHost.m_enmStatus == Weather::Host::STATUS_UNKNOWN ) { if ( clsHost.Aggregate(clsGroups) > 0 ) { ptrThread = new Weather::Host::ThreadObjects(clsHost, clsConfig["temporary_directory"], clsLogStd, clsLogErr); // // Start the host thread // clsHost.m_enmStatus = Weather::Host::STATUS_STARTING; if ( UTIL::ThreadStart((ftnThreadFunc)(Weather::Host::DownloadProductsThread), (unsigned int)(ptrThread), 1, NULL) == 0 ) { clsLogErr.Printf("ERROR: Could not start thread for host %s", clsHost.m_ptrName); clsHost.m_enmStatus = Weather::Host::STATUS_ERROR; delete ptrThread; } else { clsLogStd.Printf("Thread started for %s (%i threads running)", clsHost.m_ptrName, ++uintCurrentThreads); blnActive = true; } } else { clsHost.m_enmStatus = Weather::Host::STATUS_EMPTY; clsLogStd.Printf("No products for %s", clsHost.m_ptrName); } ptrHostIndex++; } } } else { // // For some reason we should stop (system reboot, etc.) // for (ptrHostStart = clsHosts.begin(); ptrHostStart != ptrHostEnd; ptrHostStart++) { (*ptrHostStart)->m_blnShouldBeRunning = false; } } if ( blnActive == false ) Sleep(1000); } // // Split the downloaded files // for (ptrGroupStart = clsGroups.begin(); ptrGroupStart != ptrGroupEnd; ptrGroupStart++) { (*ptrGroupStart)->Split(clsLogStd, clsLogErr); } clsConfig.Finish(); clsOutErr.Finish(); clsLogErr.Finish(); clsMutex.Finish(); clsLogStd.Printf("Finished (took %u seconds)", (int)(time(NULL)) - intTime); clsLogStd.Finish(); clsOutStd.Finish(); clsArchive.Finish(); //#ifdef UTIL_DEBUG //g_clsCMemory.Report(); //g_clsCppMemory.Report(); // UTIL::MemoryManager::Summary(g_ptrMemory, 2); //#endif return 0; }