Changeset 11473 for trunk/module-stat.c
- Timestamp:
- 01/18/19 20:17:57 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/module-stat.c
r11322 r11473 18 18 #include "oscam-time.h" 19 19 20 #define UNDEF_AVG_TIME 99999 //NOT set here 0 or small value! Could cause there reader get selected20 #define UNDEF_AVG_TIME 99999 // NOT set here 0 or small value! Could cause there reader get selected 21 21 #define MAX_ECM_SEND_CACHE 16 22 22 … … 130 130 char *ptr, *saveptr1 = NULL; 131 131 char *split[12]; 132 132 133 133 while(fgets(line, LINESIZE, file)) 134 134 { … … 146 146 } 147 147 148 if(type == 1) //New format - faster parsing:148 if(type == 1) // New format - faster parsing: 149 149 { 150 150 for(i = 0, ptr = strtok_r(line, ",", &saveptr1); ptr && i < 12 ; ptr = strtok_r(NULL, ",", &saveptr1), i++) … … 166 166 } 167 167 } 168 else //Old format - keep for compatibility:168 else // Old format - keep for compatibility: 169 169 { 170 170 i = sscanf(line, "%255s rc %04d caid %04hX prid %06X srvid %04hX time avg %d ms ecms %d last %ld fail %d len %02hX\n", … … 176 176 if(valid && s->ecmlen > 0) 177 177 { 178 179 178 if(rdr == NULL || strcmp(buf, rdr->label) != 0) 180 179 { … … 214 213 fclose(file); 215 214 NULLFREE(line); 216 215 217 216 cs_ftime(&te); 218 217 #ifdef WITH_DEBUG … … 259 258 break; 260 259 } 261 if(!q->ecmlen) //Query without ecmlen from dvbapi260 if(!q->ecmlen) // Query without ecmlen from dvbapi 262 261 { break; } 263 262 } … … 265 264 if(lock) { cs_readunlock(__func__, &rdr->lb_stat_lock); } 266 265 267 // Move stat to list start for faster access:266 // Move stat to list start for faster access: 268 267 if (i > 10 && s && !rdr->lb_stat_busy) { 269 268 if (lock) cs_writelock(__func__, &rdr->lb_stat_lock); … … 344 343 { 345 344 rdr->lb_stat_busy = 1; 346 345 347 346 cs_writelock(__func__, &rdr->lb_stat_lock); 348 347 LL_ITER it = ll_iter_create(rdr->lb_stat); … … 351 350 { 352 351 int64_t gone = comp_timeb(&ts, &s->last_received); 353 if(gone > cleanup_timeout || !s->ecmlen) //cleanup old stats352 if(gone > cleanup_timeout || !s->ecmlen) // cleanup old stats 354 353 { 355 354 ll_iter_remove_data(&it); … … 368 367 369 368 count++; 370 // if (count % 500 == 0) { //Saving stats is using too much cpu and causes high file load. so we need a break371 // 372 // 373 // 374 // 369 //if(count % 500 == 0) { // Saving stats is using too much cpu and causes high file load. so we need a break 370 // cs_readunlock(__func__, &rdr->lb_stat_lock); 371 // cs_sleepms(100); 372 // cs_readlock(__func__, &rdr->lb_stat_lock); 373 //} 375 374 } 376 375 cs_writeunlock(__func__, &rdr->lb_stat_lock); 377 376 378 377 rdr->lb_stat_busy = 0; 379 378 } … … 413 412 if (rdr->lb_stat_busy) 414 413 return NULL; 415 414 416 415 if(!rdr->lb_stat) 417 416 { … … 432 431 s->chid = q->chid; 433 432 s->ecmlen = q->ecmlen; 434 s->time_avg = UNDEF_AVG_TIME; // dummy placeholder435 s->rc = E_FOUND; //set to found--> do not change!433 s->time_avg = UNDEF_AVG_TIME; // dummy placeholder 434 s->rc = E_FOUND; // set to found--> do not change! 436 435 cs_ftime(&s->last_received); 437 436 s->fail_factor = 0; … … 508 507 509 508 510 // IGNORE stats for fallback reader with lb_force_fallback parameter509 // IGNORE stats for fallback reader with lb_force_fallback parameter 511 510 if(chk_is_fixed_fallback(rdr, er) && rdr->lb_force_fallback) 512 513 514 515 // IGNORE fails for ratelimit check511 { return; } 512 513 514 // IGNORE fails for ratelimit check 516 515 if(rc == E_NOTFOUND && rcEx == E2_RATELIMIT) 517 516 { … … 528 527 529 528 530 // IGNORE fails when reader has positive services defined in new lb_whitelist_services parameter! See ticket #3310,#3311529 // IGNORE fails when reader has positive services defined in new lb_whitelist_services parameter! See ticket #3310,#3311 531 530 if(rc >= E_NOTFOUND && has_lb_srvid(cl, er)) 532 531 { … … 537 536 format_ecm(er, buf, ECM_FMT_LEN); 538 537 cs_log_dbg(D_LB, "loadbalancer: NOT adding stat (blocking) for reader %s because has positive srvid: rc %d %s time %d ms", 539 538 rdr->label, rc, buf, ecm_time); 540 539 } 541 540 #endif … … 544 543 545 544 546 // IGNORE fails for sleep CMD08545 // IGNORE fails for sleep CMD08 547 546 if(rc == E_NOTFOUND && rdr->client->stopped==2) 548 547 { … … 557 556 return; 558 557 } 559 560 // IGNORE timeouts on local readers (they could be busy handling an emm or entitlement refresh)558 559 // IGNORE timeouts on local readers (they could be busy handling an emm or entitlement refresh) 561 560 if(rc == E_TIMEOUT && !is_network_reader(rdr)) 562 561 { … … 569 568 return; 570 569 } 571 572 // IGNORE unhandled ecmresponses570 571 // IGNORE unhandled ecmresponses 573 572 if(rc == E_UNHANDLED) 574 573 { … … 582 581 } 583 582 584 // ignore too old ecms583 // ignore too old ecms 585 584 if((uint32_t)ecm_time >= 3 * cfg.ctimeout) 586 585 { return; } … … 597 596 struct timeb now; 598 597 cs_ftime(&now); 599 598 600 599 cs_ftime(&s->last_received); 601 600 602 if(rc == E_FOUND) //found601 if(rc == E_FOUND) // found 603 602 { 604 603 … … 607 606 s->fail_factor = 0; 608 607 609 // FASTEST READER:608 // FASTEST READER: 610 609 s->time_idx++; 611 610 if(s->time_idx >= LB_MAX_STAT_TIME) … … 614 613 calc_stat(s); 615 614 616 // OLDEST READER now set by get best reader!617 618 619 // USAGELEVEL:615 // OLDEST READER now set by get best reader! 616 617 618 // USAGELEVEL: 620 619 /* Assign a value to rdr->lb_usagelevel_ecmcount, 621 620 because no determined value was assigned before. */ … … 634 633 635 634 } 636 else if(rc == E_NOTFOUND || rc == E_TIMEOUT || rc == E_FAKE) //not found / timeout /fake635 else if(rc == E_NOTFOUND || rc == E_TIMEOUT || rc == E_FAKE) // not found / timeout /fake 637 636 { 638 637 inc_fail(s); 639 638 s->rc = rc; 640 639 } 641 else if(rc == E_INVALID) //invalid640 else if(rc == E_INVALID) // invalid 642 641 { 643 642 s->rc = rc; … … 651 650 format_ecm(er, buf, ECM_FMT_LEN); 652 651 cs_log_dbg(D_LB, "loadbalancer: not handled stat for reader %s: rc %d %s time %d ms", 653 652 rdr->label, rc, buf, ecm_time); 654 653 } 655 654 #endif … … 665 664 format_ecm(er, buf, ECM_FMT_LEN); 666 665 cs_log_dbg(D_LB, "loadbalancer: adding stat for reader %s: rc %d %s time %d ms fail %d", 667 666 rdr->label, rc, buf, ecm_time, s->fail_factor); 668 667 } 669 668 #endif … … 721 720 { 722 721 if (rdr->lb_stat_busy) return 0; 723 722 724 723 rdr->lb_stat_busy = 1; 725 724 cs_writelock(__func__, &rdr->lb_stat_lock); … … 748 747 static int32_t has_ident(FTAB *ftab, ECM_REQUEST *er) { 749 748 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 749 if (!ftab || !ftab->filts) 750 return 0; 751 752 int32_t j, k; 753 754 for (j = 0; j < ftab->nfilts; j++) { 755 if (ftab->filts[j].caid) { 756 if (ftab->filts[j].caid==er->caid) { //caid matches! 757 int32_t nprids = ftab->filts[j].nprids; 758 if (!nprids) // No Provider ->Ok 759 return 1; 760 761 for (k = 0; k < nprids; k++) { 762 uint32_t prid = ftab->filts[j].prids[k]; 763 if (prid == er->prid) { //Provider matches 764 return 1; 765 } 766 } 767 } 768 } 769 } 770 return 0; //No match! 772 771 }*/ 773 772 … … 777 776 } 778 777 779 780 778 static int32_t get_nfb_readers(ECM_REQUEST *er) 781 779 { 782 783 780 int32_t nfb_readers = er->client->account->lb_nfb_readers == -1 ? cfg.lb_nfb_readers : er->client->account->lb_nfb_readers; 784 781 … … 787 784 return nfb_readers; 788 785 } 789 790 786 791 787 static int32_t get_nbest_readers(ECM_REQUEST *er) … … 799 795 static void convert_to_beta_int(ECM_REQUEST *er, uint16_t caid_to) 800 796 { 801 u nsigned charmd5tmp[MD5_DIGEST_LENGTH];797 uint8_t md5tmp[MD5_DIGEST_LENGTH]; 802 798 convert_to_beta(er->client, er, caid_to); 803 799 // update ecmd5 for store ECM in cache 804 800 memcpy(er->ecmd5, MD5(er->ecm + 13, er->ecmlen - 13, md5tmp), CS_ECMSTORESIZE); 805 801 cacheex_update_hash(er); 806 er->btun = 2; //marked as auto-betatunnel converted. Also for fixing recursive lock in get_cw 807 } 808 802 er->btun = 2; // marked as auto-betatunnel converted. Also for fixing recursive lock in get_cw 803 } 809 804 810 805 static void convert_to_nagra_int(ECM_REQUEST *er, uint16_t caid_to) 811 806 { 812 u nsigned charmd5tmp[MD5_DIGEST_LENGTH];807 uint8_t md5tmp[MD5_DIGEST_LENGTH]; 813 808 convert_to_nagra(er->client, er, caid_to); 814 809 // update ecmd5 for store ECM in cache 815 810 memcpy(er->ecmd5, MD5(er->ecm + 3, er->ecmlen - 3, md5tmp), CS_ECMSTORESIZE); 816 811 cacheex_update_hash(er); 817 er->btun = 2; // marked as auto-betatunnel converted. Also for fixing recursive lock in get_cw812 er->btun = 2; // marked as auto-betatunnel converted. Also for fixing recursive lock in get_cw 818 813 } 819 814 … … 883 878 } 884 879 885 886 880 void check_lb_auto_betatunnel_mode(ECM_REQUEST *er) 887 881 { … … 899 893 er->caid = 0x1835; 900 894 } 901 // //no other way to autodetect is 1801,1834 or 1835895 // no other way to autodetect 1801, 1834 or 1835 902 896 } 903 897 … … 906 900 if(is_network_reader(rdr)) 907 901 { 908 return 0; // reader caid is not real caid902 return 0; // reader caid is not real caid 909 903 } 910 904 else … … 952 946 struct s_reader *rdr; 953 947 954 955 948 for(ea = er->matching_rdr; ea; ea = ea->next) 956 949 { … … 965 958 } 966 959 967 // if force_reopen we must active the "valid" reader960 // if force_reopen we must active the "valid" reader 968 961 if(s->rc != E_FOUND && (*force_reopen) && cfg.lb_force_reopen_always) 969 962 { … … 994 987 } 995 988 996 if(s->rc != E_FOUND) //for debug output989 if(s->rc != E_FOUND) // for debug output 997 990 { 998 991 cs_log_dbg(D_LB, "loadbalancer: reader %s blocked for %d seconds (fail_factor %d), retrying in %d seconds", rdr->label, get_reopen_seconds(s), s->fail_factor, (uint) (reopenseconds - (gone/1000))); … … 1000 993 } 1001 994 1002 if(s->rc == E_FOUND) //for debug output995 if(s->rc == E_FOUND) // for debug output 1003 996 { cs_log_dbg(D_LB, "loadbalancer: reader %s \"e_found\" but not selected for lbvalue check", rdr->label); } 1004 997 1005 998 } 1006 999 } 1007 1008 1009 1000 1010 1001 /** … … 1032 1023 get_stat_query(er, &q); 1033 1024 1034 1035 //auto-betatunnel: The trick is: "let the loadbalancer decide"! 1036 if(cfg.lb_auto_betatunnel && caid_is_nagra(er->caid) && er->ecmlen) //nagra 1025 // auto-betatunnel: The trick is: "let the loadbalancer decide"! 1026 if(cfg.lb_auto_betatunnel && caid_is_nagra(er->caid) && er->ecmlen) // nagra 1037 1027 { 1038 1028 uint16_t caid_to = __lb_get_betatunnel_caid_to(er->caid); … … 1041 1031 int8_t needs_stats_nagra = 1, needs_stats_beta = 1; 1042 1032 1043 // Clone query parameters for beta:1033 // Clone query parameters for beta: 1044 1034 STAT_QUERY qbeta = q; 1045 1035 qbeta.caid = caid_to; … … 1055 1045 READER_STAT *stat_beta = NULL; 1056 1046 1057 // What is faster? nagra or beta?1047 // What is faster? nagra or beta? 1058 1048 int8_t isn; 1059 1049 int8_t isb; … … 1068 1058 if(weight <= 0) { weight = 1; } 1069 1059 1070 1071 //Check if betatunnel is allowed on this reader: 1060 // Check if betatunnel is allowed on this reader: 1072 1061 int8_t valid = chk_ctab(caid_to, &rdr->ctab) //Check caid 1073 1074 1075 1062 && chk_rfilter2(caid_to, 0, rdr) //Ident 1063 && chk_srvid_by_caid_prov_rdr(rdr, caid_to, 0) //Services 1064 && (!get_rdr_caid(rdr) || chk_caid_rdr(rdr, caid_to)); //rdr-caid 1076 1065 if(valid) 1077 1066 { … … 1082 1071 //stat_beta = NULL; 1083 1072 1084 // Check if nagra is allowed on this reader:1073 // Check if nagra is allowed on this reader: 1085 1074 int8_t nvalid = chk_ctab(er->caid, &rdr->ctab)//Check caid 1086 1075 && chk_rfilter2(er->caid, 0, rdr) //Ident … … 1093 1082 } 1094 1083 1095 // calculate nagra data:1084 // calculate nagra data: 1096 1085 if(stat_nagra && stat_nagra->rc == E_FOUND) 1097 1086 { … … 1101 1090 } 1102 1091 1103 // calculate beta data:1092 // calculate beta data: 1104 1093 if(stat_beta && stat_beta->rc == E_FOUND) 1105 1094 { … … 1109 1098 } 1110 1099 1111 // Uncomplete reader evaluation, we need more stats!1100 // Uncomplete reader evaluation, we need more stats! 1112 1101 if(stat_nagra) 1113 1102 { … … 1123 1112 } 1124 1113 1125 if(!overall_valid) // we have no valid betatunnel reader also we don't needs stats (converted)1114 if(!overall_valid) // we have no valid betatunnel reader also we don't needs stats (converted) 1126 1115 { needs_stats_beta = 0; } 1127 1116 1128 if(!overall_nvalid) //we have no valid reader also we don't needs stats (unconverted)1117 if(!overall_nvalid) // we have no valid reader also we don't needs stats (unconverted) 1129 1118 { needs_stats_nagra = 0; } 1130 1119 … … 1139 1128 { 1140 1129 cs_log_dbg(D_LB, "loadbalancer-betatunnel %04X:%04X (%d/%d) needs more statistics...", er->caid, caid_to, 1141 1142 if(needs_stats_beta) //try beta first1130 needs_stats_nagra, needs_stats_beta); 1131 if(needs_stats_beta) // try beta first 1143 1132 { 1144 1133 … … 1161 1150 } 1162 1151 else 1163 1164 1165 if(cfg.lb_auto_betatunnel && (er->caid == 0x1702 || er->caid == 0x1722) && er->ocaid == 0x0000 && er->ecmlen) //beta 1152 { 1153 if(cfg.lb_auto_betatunnel && (er->caid == 0x1702 || er->caid == 0x1722) && er->ocaid == 0x0000 && er->ecmlen) // beta 1166 1154 { 1167 1155 uint16_t caid_to = __lb_get_betatunnel_caid_to(er->caid); … … 1170 1158 int8_t needs_stats_nagra = 1, needs_stats_beta = 1; 1171 1159 1172 // Clone query parameters for beta:1160 // Clone query parameters for beta: 1173 1161 STAT_QUERY qnagra = q; 1174 1162 qnagra.caid = caid_to; … … 1196 1184 if(weight <= 0) { weight = 1; } 1197 1185 1198 1199 1200 1186 //Check if reverse betatunnel is allowed on this reader: 1201 1187 int8_t valid = chk_ctab(caid_to, &rdr->ctab)//, rdr->typ) //Check caid 1202 1203 1204 1188 && chk_rfilter2(caid_to, 0, rdr) //Ident 1189 && chk_srvid_by_caid_prov_rdr(rdr, caid_to, 0) //Services 1190 && (!get_rdr_caid(rdr) || chk_caid_rdr(rdr, caid_to)); //rdr-caid 1205 1191 if(valid) 1206 1192 { … … 1211 1197 //stat_nagra = NULL; 1212 1198 1213 // Check if beta is allowed on this reader:1199 // Check if beta is allowed on this reader: 1214 1200 int8_t bvalid = chk_ctab(er->caid, &rdr->ctab)//, rdr->typ) //Check caid 1215 1201 && chk_rfilter2(er->caid, 0, rdr) //Ident … … 1222 1208 } 1223 1209 1224 // calculate nagra data:1210 // calculate nagra data: 1225 1211 if(stat_nagra && stat_nagra->rc == E_FOUND) 1226 1212 { … … 1230 1216 } 1231 1217 1232 // calculate beta data:1218 // calculate beta data: 1233 1219 if(stat_beta && stat_beta->rc == E_FOUND) 1234 1220 { … … 1238 1224 } 1239 1225 1240 // Uncomplete reader evaluation, we need more stats!1226 // Uncomplete reader evaluation, we need more stats! 1241 1227 if(stat_beta) 1242 1228 { … … 1252 1238 } 1253 1239 1254 if(!overall_valid) // we have no valid reverse betatunnel reader also we don't needs stats (converted)1240 if(!overall_valid) // we have no valid reverse betatunnel reader also we don't needs stats (converted) 1255 1241 { needs_stats_nagra = 0; } 1256 1242 1257 if(!overall_bvalid) //we have no valid reader also we don't needs stats (unconverted)1243 if(!overall_bvalid) // we have no valid reader also we don't needs stats (unconverted) 1258 1244 { needs_stats_beta = 0; } 1259 1245 … … 1265 1251 } 1266 1252 1267 // if we needs stats, we send 2 ecm requests: 18xx and 17xx:1253 // if we needs stats, we send 2 ecm requests: 18xx and 17xx: 1268 1254 if(needs_stats_nagra || needs_stats_beta) 1269 1255 { 1270 1256 cs_log_dbg(D_LB, "loadbalancer-betatunnel %04X:%04X (%d/%d) needs more statistics...", er->caid, caid_to, 1271 1272 if(needs_stats_nagra) 1257 needs_stats_beta, needs_stats_nagra); 1258 if(needs_stats_nagra) // try nagra frist 1273 1259 { 1274 1260 … … 1291 1277 } 1292 1278 } 1279 } 1293 1280 1294 1281 if(cfg.lb_auto_betatunnel && chk_is_betatunnel_caid(er->caid)) 1295 1282 { 1296 // check again is caid valied to reader1297 // with both caid on local readers or with proxy1298 // (both caid will setup to reader for make tunnel caid in share (ccc) visible)1299 // make sure dosn't send a beta ecm to nagra reader (or reverse)1283 // check again is caid valied to reader 1284 // with both caid on local readers or with proxy 1285 // (both caid will setup to reader for make tunnel caid in share (ccc) visible) 1286 // make sure dosn't send a beta ecm to nagra reader (or reverse) 1300 1287 struct s_ecm_answer *prv = NULL; 1301 1288 for(ea = er->matching_rdr; ea; ea = ea->next) 1302 1289 { 1303 1290 rdr = ea->reader; 1304 if(is_network_reader(rdr)) //reader caid is not real caid1291 if(is_network_reader(rdr)) // reader caid is not real caid 1305 1292 { 1306 1293 prv = ea; … … 1308 1295 } 1309 1296 cs_log_dbg(D_LB, "check again caid %04X on reader %s", er->caid, rdr->label); 1297 1310 1298 if(!get_rdr_caid(ea->reader) || chk_caid_rdr(ea->reader, er->caid)) 1311 1299 { … … 1324 1312 } 1325 1313 } 1314 1326 1315 if(!er->reader_avail) 1327 1316 { return; } … … 1340 1329 1341 1330 1342 if(!nreaders) 1331 if(!nreaders) // if is configured zero -> replace it by -1 (default means unlimited!) 1343 1332 { nreaders = -1; } 1344 1333 else if(nreaders <= nbest_readers) 1345 { nreaders = nbest_readers + 1; } // nreaders must cover nbest more 1 reader for try to unblock/add stats1334 { nreaders = nbest_readers + 1; } // nreaders must cover nbest more 1 reader for try to unblock/add stats 1346 1335 1347 1336 int32_t reader_active = 0; 1348 int32_t max_reopen = nreaders - nbest_readers; // if nreaders=-1, we try to reopen all readers1337 int32_t max_reopen = nreaders - nbest_readers; // if nreaders=-1, we try to reopen all readers 1349 1338 1350 1339 … … 1362 1351 { 1363 1352 nr++; 1364 1365 1353 if(nr > 5) { continue; } 1366 1354 … … 1380 1368 1381 1369 cs_log_dbg(D_LB, "loadbalancer: client %s for %s: n=%d valid readers: %s", 1382 1370 username(er->client), ecmbuf, nr, buf); 1383 1371 } 1384 1372 #endif 1385 1386 1373 1387 1374 //Deactive all matching readers and set ea->value = 0; … … 1397 1384 1398 1385 1399 // Here evaluate lbvalue for readers with valid statistics1386 // Here evaluate lbvalue for readers with valid statistics 1400 1387 for(ea = er->matching_rdr; ea; ea = ea->next) 1401 1388 { 1402 1403 1389 rdr = ea->reader; 1404 1390 s = get_stat(rdr, &q); 1405 1391 1406 1407 1392 int32_t weight = rdr->lb_weight <= 0 ? 100 : rdr->lb_weight; 1408 1393 //struct s_client *cl = rdr->client; 1409 1394 1410 1395 if(s && s->rc == E_FOUND 1411 && s->ecm_count >= cfg.lb_min_ecmcount 1412 && (s->ecm_count <= cfg.lb_max_ecmcount || (retrylimit && s->time_avg <= retrylimit)) 1413 ) 1414 { 1415 1416 //Reader can decode this service (rc==0) and has lb_min_ecmcount ecms: 1396 && s->ecm_count >= cfg.lb_min_ecmcount 1397 && (s->ecm_count <= cfg.lb_max_ecmcount || (retrylimit && s->time_avg <= retrylimit))) 1398 { 1399 // Reader can decode this service (rc==0) and has lb_min_ecmcount ecms: 1417 1400 if(er->preferlocalcards && (ea->status & READER_LOCAL)) 1418 { nlocal_readers++; } // Prefer local readers!1401 { nlocal_readers++; } // Prefer local readers! 1419 1402 1420 1403 switch(cfg.lb_mode) 1421 1404 { 1422 case LB_FASTEST_READER_FIRST: 1423 current = s->time_avg * 100 / weight; 1424 break; 1425 1426 case LB_OLDEST_READER_FIRST: 1427 if(!rdr->lb_last.time) 1428 { rdr->lb_last = check_time; } 1429 1430 //current is negative here! 1431 current = comp_timeb(&rdr->lb_last, &check_time); 1432 1433 current = current * weight / 100; 1434 1435 if(!current) { current = -1; } 1436 1437 //handle retrylimit 1438 if(retrylimit) 1405 case LB_FASTEST_READER_FIRST: 1406 current = s->time_avg * 100 / weight; 1407 break; 1408 1409 case LB_OLDEST_READER_FIRST: 1410 if(!rdr->lb_last.time) 1411 { rdr->lb_last = check_time; } 1412 1413 //current is negative here! 1414 current = comp_timeb(&rdr->lb_last, &check_time); 1415 current = current * weight / 100; 1416 if(!current) { current = -1; } 1417 1418 //handle retrylimit 1419 if(retrylimit) 1420 { 1421 if(s->time_avg > retrylimit) // set lowest value for reader with time-avg>retrylimit 1422 { 1423 current = s->time_avg; // in this way, it will choose best time-avg reader among the worst ones 1424 } 1425 else 1426 { 1427 current = current - 1; // so when all have same current, it prioritizes the one with s->time_avg<=retrylimit! This avoid a loop! 1428 } 1429 } 1430 break; 1431 1432 case LB_LOWEST_USAGELEVEL: 1433 current = rdr->lb_usagelevel * 100 / weight; 1434 1435 //handle retrylimit 1436 if(retrylimit) 1437 { 1438 if(s->time_avg > retrylimit) 1439 { current = 1000; } //set lowest value for reader with time-avg>retrylimit 1440 else 1441 { current = current - 1; } //so when all reaches retrylimit (all have lb_value=1000) or all have same current, it prioritizes the one with s->time_avg<=retrylimit! This avoid a loop! 1442 } 1443 break; 1444 } 1445 1446 if(cfg.lb_mode != LB_OLDEST_READER_FIRST) // Adjust selection to reader load: 1447 { 1448 /*if(rdr->ph.c_available && !rdr->ph.c_available(rdr, AVAIL_CHECK_LOADBALANCE, er)) 1439 1449 { 1440 if(s->time_avg > retrylimit){ //set lowest value for reader with time-avg>retrylimit 1441 current = s->time_avg; //in this way, it will choose best time-avg reader among the worst ones 1442 }else{ 1443 current = current - 1; //so when all have same current, it prioritizes the one with s->time_avg<=retrylimit! This avoid a loop! 1444 } 1450 current=current*2; 1445 1451 } 1446 1452 1447 break; 1448 1449 case LB_LOWEST_USAGELEVEL: 1450 current = rdr->lb_usagelevel * 100 / weight; 1451 1452 //handle retrylimit 1453 if(retrylimit) 1454 { 1455 if(s->time_avg > retrylimit) 1456 { current = 1000; } //set lowest value for reader with time-avg>retrylimit 1457 else 1458 { current = current - 1; } //so when all reaches retrylimit (all have lb_value=1000) or all have same current, it prioritizes the one with s->time_avg<=retrylimit! This avoid a loop! 1459 } 1460 1461 break; 1462 } 1463 1464 if(cfg.lb_mode != LB_OLDEST_READER_FIRST) //Adjust selection to reader load: 1465 { 1466 /* if (rdr->ph.c_available && !rdr->ph.c_available(rdr, AVAIL_CHECK_LOADBALANCE, er)) { 1467 current=current*2; 1468 } 1469 1470 if (cl && cl->pending) 1471 current=current*cl->pending; 1453 if(cl && cl->pending) 1454 current=current*cl->pending; 1472 1455 */ 1473 1456 if(current < 1) … … 1475 1458 } 1476 1459 1477 1478 1460 cs_log_dbg(D_LB, "loadbalancer: reader %s lbvalue = %d (time-avg %d)", rdr->label, (int) llabs(current), s->time_avg); 1479 1461 … … 1481 1463 rdr->lbvalue = llabs(current); 1482 1464 #endif 1483 1484 1465 ea->value = current; 1485 1466 ea->time = s->time_avg; … … 1487 1468 } 1488 1469 1489 // check for local readers1490 if(nlocal_readers > nbest_readers) //if we have local readers, we prefer them!1470 // check for local readers 1471 if(nlocal_readers > nbest_readers) // if we have local readers, we prefer them! 1491 1472 { 1492 1473 nlocal_readers = nbest_readers; … … 1494 1475 } 1495 1476 else 1496 { nbest_readers = nbest_readers - nlocal_readers; } 1497 1477 { 1478 nbest_readers = nbest_readers - nlocal_readers; 1479 } 1498 1480 1499 1481 struct s_reader *best_rdr = NULL; … … 1501 1483 int32_t best_time = 0; 1502 1484 1503 // Here choose nbest readers. We evaluate only readers with valid stats (they have ea->value>0, calculated above)1485 // Here choose nbest readers. We evaluate only readers with valid stats (they have ea->value>0, calculated above) 1504 1486 while(1) 1505 1487 { … … 1514 1496 { best = ea; } 1515 1497 } 1498 1516 1499 if(!best) 1517 1500 { break; } … … 1524 1507 } 1525 1508 1526 if(nlocal_readers) //primary readers, local1509 if(nlocal_readers) // primary readers, local 1527 1510 { 1528 1511 nlocal_readers--; 1529 1512 reader_active++; 1530 1513 best->status |= READER_ACTIVE; 1531 1514 best->value = 0; 1532 1515 cs_log_dbg(D_LB, "loadbalancer: reader %s --> ACTIVE", best_rdri->label); 1533 1516 } 1534 else if(nbest_readers) //primary readers, other1517 else if(nbest_readers) // primary readers, other 1535 1518 { 1536 1519 nbest_readers--; 1537 1520 reader_active++; 1538 1521 best->status |= READER_ACTIVE; 1539 1522 best->value = 0; 1540 1523 cs_log_dbg(D_LB, "loadbalancer: reader %s --> ACTIVE", best_rdri->label); 1541 1524 } … … 1543 1526 { break; } 1544 1527 } 1545 1546 1528 1547 1529 /* Here choose nfb_readers … … 1574 1556 s = get_stat(rdr, &q); 1575 1557 if(s && s->rc == E_FOUND 1576 && s->ecm_count >= cfg.lb_min_ecmcount 1577 && (s->ecm_count <= cfg.lb_max_ecmcount || (retrylimit && s->time_avg <= retrylimit)) 1578 ) 1558 && s->ecm_count >= cfg.lb_min_ecmcount 1559 && (s->ecm_count <= cfg.lb_max_ecmcount || (retrylimit && s->time_avg <= retrylimit))) 1579 1560 { 1580 1561 nfb_readers--; … … 1607 1588 cs_log_dbg(D_LB, "loadbalancer: reader %s --> FALLBACK", best->reader->label); 1608 1589 } 1609 //end fallback readers 1610 1611 1612 1613 //ACTIVE readers with no stats, or with no lb_min_ecmcount, or lb_max_ecmcount reached --> NO use max_reopen for these readers, always open! 1590 // end fallback readers 1591 1592 // ACTIVE readers with no stats, or with no lb_min_ecmcount, or lb_max_ecmcount reached --> NO use max_reopen for these readers, always open! 1614 1593 for(ea = er->matching_rdr; ea; ea = ea->next) 1615 1594 { … … 1617 1596 s = get_stat(rdr, &q); 1618 1597 1619 1620 1598 #ifdef CS_CACHEEX 1621 // if cacheex reader, always active and no stats1599 // if cacheex reader, always active and no stats 1622 1600 if(rdr->cacheex.mode == 1) 1623 1601 { … … 1626 1604 } 1627 1605 #endif 1628 1629 //ignore fixed fallback with lb_force_fallback=1: no need stats, always used as fallaback! 1606 // ignore fixed fallback with lb_force_fallback=1: no need stats, always used as fallaback! 1630 1607 if(chk_is_fixed_fallback(rdr, er) && rdr->lb_force_fallback) 1631 1608 continue; 1632 1609 1633 // active readers with no stats1610 // active readers with no stats 1634 1611 if(!s) 1635 1612 { … … 1640 1617 } 1641 1618 1642 // active readers with no lb_min_ecmcount reached1619 // active readers with no lb_min_ecmcount reached 1643 1620 if(s->rc == E_FOUND && s->ecm_count < cfg.lb_min_ecmcount) 1644 1621 { … … 1649 1626 } 1650 1627 1651 // reset stats and active readers reach cfg.lb_max_ecmcount and time_avg > retrylimit.1628 // reset stats and active readers reach cfg.lb_max_ecmcount and time_avg > retrylimit. 1652 1629 if(s->rc == E_FOUND && s->ecm_count > cfg.lb_max_ecmcount && (!retrylimit || s->time_avg > retrylimit)) 1653 1630 { 1654 1631 cs_log_dbg(D_LB, "loadbalancer: reader %s reaches max ecms (%d), resetting statistics --> ACTIVE", rdr->label, cfg.lb_max_ecmcount); 1655 reset_ecmcount_reader(s, rdr); // ecm_count=01656 reset_avgtime_reader(s, rdr); // time_avg=01632 reset_ecmcount_reader(s, rdr); // ecm_count=0 1633 reset_avgtime_reader(s, rdr); // time_avg=0 1657 1634 ea->status |= READER_ACTIVE; 1658 1635 reader_active++; … … 1663 1640 cs_ftime(&now); 1664 1641 int64_t gone = comp_timeb(&now, &s->last_received); 1665 // reset avg-time and active reader with s->last_received older than 5 min and avg-time>retrylimit1642 // reset avg-time and active reader with s->last_received older than 5 min and avg-time>retrylimit 1666 1643 if(retrylimit && s->rc == E_FOUND && (gone >= 300*1000) && s->time_avg > retrylimit) 1667 1644 { 1668 1645 cs_log_dbg(D_LB, "loadbalancer: reader %s has time-avg>retrylimit and last received older than 5 minutes, resetting avg-time --> ACTIVE", rdr->label); 1669 reset_avgtime_reader(s, rdr); // time_avg=01670 ea->status &= ~(READER_ACTIVE | READER_FALLBACK); // It could be activated as fallback above because has lb_vlaue>0, so remove fallback state!1646 reset_avgtime_reader(s, rdr); // time_avg=0 1647 ea->status &= ~(READER_ACTIVE | READER_FALLBACK); // It could be activated as fallback above because has lb_vlaue>0, so remove fallback state! 1671 1648 ea->status |= READER_ACTIVE; 1672 1649 reader_active++; … … 1675 1652 } 1676 1653 1677 1678 1654 int32_t force_reopen = 0; 1679 1680 1655 1681 1656 //no reader active --> force to reopen matching readers … … 1687 1662 else if(retrylimit) 1688 1663 { 1689 1690 1664 /* 1691 1665 * check for lbretrylimit! … … 1708 1682 //reset avg time and ACTIVE all valid lbvalue readers 1709 1683 if(s && s->rc == E_FOUND 1710 && s->ecm_count >= cfg.lb_min_ecmcount 1711 && (s->ecm_count <= cfg.lb_max_ecmcount || s->time_avg <= retrylimit) 1712 ) 1684 && s->ecm_count >= cfg.lb_min_ecmcount 1685 && (s->ecm_count <= cfg.lb_max_ecmcount || s->time_avg <= retrylimit)) 1713 1686 { 1714 1687 if((ea->status & READER_FALLBACK)) { cs_log_dbg(D_LB, "loadbalancer: reader %s selected as FALLBACK --> ACTIVE", rdr->label); } … … 1730 1703 } 1731 1704 1732 1733 1705 //try to reopen max_reopen blocked readers (readers with last ecm not "e_found"); if force_reopen=1, force reopen valid blocked readers! 1734 1706 try_open_blocked_readers(er, &q, &max_reopen, &force_reopen); 1735 1707 1736 1737 1708 cs_log_dbg(D_LB, "loadbalancer: --------------------------------------------"); 1738 1739 1740 1709 1741 1710 #ifdef WITH_DEBUG … … 1756 1725 1757 1726 nr++; 1758 1759 1727 if(nr > 5) { continue; } 1760 1728 … … 1774 1742 1775 1743 cs_log_dbg(D_LB, "loadbalancer: client %s for %s: n=%d selected readers: %s", 1776 1744 username(er->client), ecmbuf, nr, buf); 1777 1745 } 1778 1746 #endif 1779 1747 return; 1780 1748 } 1781 1782 1783 1749 1784 1750 /** … … 1812 1778 set_thread_name(__func__); 1813 1779 LL_ITER itr = ll_iter_create(configured_readers); 1814 cs_readlock(__func__, &readerlist_lock); // this avoids cleaning a reading during writing1780 cs_readlock(__func__, &readerlist_lock); // this avoids cleaning a reading during writing 1815 1781 while((rdr = ll_iter_next(&itr))) 1816 1782 { … … 1821 1787 LL_ITER it = ll_iter_create(rdr->lb_stat); 1822 1788 READER_STAT *s; 1789 1823 1790 while((s = ll_iter_next(&it))) 1824 1791 { 1825 1826 1792 int64_t gone = comp_timeb(&now, &s->last_received); 1827 1793 if(gone > cleanup_timeout) … … 1844 1810 cs_ftime(&now); 1845 1811 int64_t gone = comp_timeb(&now, &last_housekeeping); 1846 if(!force && (gone < 60 *60*1000)) //only clean once in an hour1812 if(!force && (gone < 60 * 60 * 1000)) // only clean once in an hour 1847 1813 { return; } 1848 1814 … … 1942 1908 } 1943 1909 1944 1945 1910 /** 1946 1911 * Automatic timeout feature depending on statistik values … … 1964 1929 } 1965 1930 } 1931 1966 1932 if(!s) { return ctimeout; } 1967 1933 … … 1976 1942 if((int32_t)(t - s->time_avg) < cfg.lb_auto_timeout_t) { t = s->time_avg + cfg.lb_auto_timeout_t; } 1977 1943 } 1944 1978 1945 if(t > ctimeout) { t = ctimeout; } 1946 1979 1947 #ifdef WITH_DEBUG 1980 1948 if(D_TRACE & cs_dblevel) … … 2006 1974 uint16_t save_caid = er->caid; 2007 1975 er->caid = caid; 2008 match = matching_reader(er, rdr); // matching1976 match = matching_reader(er, rdr); // matching 2009 1977 er->caid = save_caid; 2010 1978 } … … 2021 1989 struct s_ecm_answer *ea_ecm = NULL, *ea_er = NULL; 2022 1990 uint8_t rdrs = 0; 2023 2024 1991 2025 1992 cs_readlock(__func__, &ecmcache_lock); … … 2090 2057 void lb_set_best_reader(ECM_REQUEST *er) 2091 2058 { 2092 if 2059 if(!cfg.lb_mode) 2093 2060 return; 2061 2094 2062 // cache2 is handled by readers queue, so, if a same ecm hash with same readers, use these same readers to get cache2 from them! Not ask other readers! 2095 2063 struct ecm_request_t *ecm_eq = NULL; … … 2100 2068 use_same_readers(er, ecm_eq); 2101 2069 cs_log_dbg(D_LB, "{client %s, caid %04X, prid %06X, srvid %04X} [get_cw] found same ecm with same readers from client %s, use them!", (check_client(er->client) ? er->client->account->usr : "-"), er->caid, er->prid, er->srvid, (check_client(ecm_eq->client) ? ecm_eq->client->account->usr : "-")); 2102 }else{ 2070 } 2071 else 2072 { 2103 2073 // FILTER readers by loadbalancing 2104 2074 stat_get_best_reader(er); … … 2112 2082 cs_ftime(&reader->lb_last); 2113 2083 } 2114 2115 2084 2116 2085 void send_reader_stat(struct s_reader *rdr, ECM_REQUEST *er, struct s_ecm_answer *ea, int8_t rc)
Note:
See TracChangeset
for help on using the changeset viewer.