/[LeafOK_CVS]/lbbs/src/section_list_loader.c
ViewVC logotype

Diff of /lbbs/src/section_list_loader.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.4 by sysadm, Tue May 27 03:25:02 2025 UTC Revision 1.5 by sysadm, Tue May 27 07:21:43 2025 UTC
# Line 28  Line 28 
28    
29  #define SECTION_LIST_LOAD_INTERVAL 10 // second  #define SECTION_LIST_LOAD_INTERVAL 10 // second
30    
31  static int section_list_loader_pid;  int section_list_loader_pid;
32    int last_article_op_log_mid;
33    
34  int load_section_config_from_db(void)  int load_section_config_from_db(void)
35  {  {
# Line 163  int append_articles_from_db(int32_t star Line 164  int append_articles_from_db(int32_t star
164          MYSQL_ROW row;          MYSQL_ROW row;
165          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
166          ARTICLE article;          ARTICLE article;
167            ARTICLE *p_topic;
168          SECTION_LIST *p_section = NULL;          SECTION_LIST *p_section = NULL;
169          int32_t last_sid = 0;          int32_t last_sid = 0;
170          int ret = 0;          int ret = 0;
# Line 176  int append_articles_from_db(int32_t star Line 178  int append_articles_from_db(int32_t star
178          }          }
179    
180          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
181                           "SELECT AID, TID, SID, CID, UID, visible, excerption, "                           "SELECT AID, TID, SID, CID, UID, visible, excerption, ontop, `lock`, "
182                           "ontop, `lock`, username, nickname, title, UNIX_TIMESTAMP(sub_dt) AS sub_dt "                           "transship, username, nickname, title, UNIX_TIMESTAMP(sub_dt) AS sub_dt "
183                           "FROM bbs WHERE AID >= %d ORDER BY AID",                           "FROM bbs WHERE AID >= %d ORDER BY AID",
184                           start_aid);                           start_aid);
185    
# Line 218  int append_articles_from_db(int32_t star Line 220  int append_articles_from_db(int32_t star
220                  article.excerption = (int8_t)atoi(row[i++]);                  article.excerption = (int8_t)atoi(row[i++]);
221                  article.ontop = (int8_t)atoi(row[i++]);                  article.ontop = (int8_t)atoi(row[i++]);
222                  article.lock = (int8_t)atoi(row[i++]);                  article.lock = (int8_t)atoi(row[i++]);
223                    article.transship = (int8_t)atoi(row[i++]);
224    
225                  strncpy(article.username, row[i++], sizeof(article.username) - 1);                  strncpy(article.username, row[i++], sizeof(article.username) - 1);
226                  article.username[sizeof(article.username) - 1] = '\0';                  article.username[sizeof(article.username) - 1] = '\0';
# Line 245  int append_articles_from_db(int32_t star Line 248  int append_articles_from_db(int32_t star
248                          break;                          break;
249                  }                  }
250    
251                    if (article.visible != 0 && article.tid != 0)
252                    {
253                            // Check if topic article is visible
254                            p_topic = article_block_find_by_aid(article.tid);
255                            if (p_topic == NULL || p_topic->visible == 0)
256                            {
257                                    // log_error("Set article (aid = %d) as invisible due to invisible or non-existing topic head\n", article.aid);
258                                    article.tid = 0;
259                                    article.visible = 0;
260                            }
261                    }
262    
263                  // acquire lock of current section if different from last one                  // acquire lock of current section if different from last one
264                  if (!global_lock && article.sid != last_sid)                  if (!global_lock && article.sid != last_sid)
265                  {                  {
# Line 293  cleanup: Line 308  cleanup:
308          return ret;          return ret;
309  }  }
310    
311    int set_last_article_op_log_from_db(void)
312    {
313            MYSQL *db;
314            MYSQL_RES *rs;
315            MYSQL_ROW row;
316            char sql[SQL_BUFFER_LEN];
317    
318            db = db_open();
319            if (db == NULL)
320            {
321                    log_error("db_open() error: %s\n", mysql_error(db));
322                    return -1;
323            }
324    
325            snprintf(sql, sizeof(sql),
326                             "SELECT MID FROM bbs_article_op ORDER BY MID DESC LIMIT 1");
327    
328            if (mysql_query(db, sql) != 0)
329            {
330                    log_error("Query article op error: %s\n", mysql_error(db));
331                    return -2;
332            }
333            if ((rs = mysql_store_result(db)) == NULL)
334            {
335                    log_error("Get article op data failed\n");
336                    return -2;
337            }
338    
339            if ((row = mysql_fetch_row(rs)))
340            {
341                    last_article_op_log_mid = atoi(row[0]);
342            }
343    
344            mysql_free_result(rs);
345    
346            mysql_close(db);
347    
348            return last_article_op_log_mid;
349    }
350    
351    int apply_article_op_log_from_db(void)
352    {
353            MYSQL *db;
354            MYSQL_RES *rs, *rs2;
355            MYSQL_ROW row, row2;
356            char sql[SQL_BUFFER_LEN];
357            ARTICLE *p_article;
358            SECTION_LIST *p_section = NULL;
359            SECTION_LIST *p_section_dest;
360            int32_t last_sid = 0;
361            int32_t sid_dest;
362            int ret = 0;
363    
364            db = db_open();
365            if (db == NULL)
366            {
367                    log_error("db_open() error: %s\n", mysql_error(db));
368                    return -3;
369            }
370    
371            snprintf(sql, sizeof(sql),
372                             "SELECT MID, AID, type FROM bbs_article_op "
373                             "WHERE MID > %d AND type NOT IN ('A', 'M') ORDER BY MID",
374                             last_article_op_log_mid);
375    
376            if (mysql_query(db, sql) != 0)
377            {
378                    log_error("Query article log error: %s\n", mysql_error(db));
379                    return -3;
380            }
381            if ((rs = mysql_store_result(db)) == NULL)
382            {
383                    log_error("Get article log data failed\n");
384                    return -3;
385            }
386    
387            while ((row = mysql_fetch_row(rs)))
388            {
389                    p_article = article_block_find_by_aid(atoi(row[1]));
390                    if (p_article == NULL) // related article has not been appended yet
391                    {
392                            ret = -2;
393                            break;
394                    }
395    
396                    // release lock of last section if different from current one
397                    if (p_article->sid != last_sid && last_sid != 0)
398                    {
399                            if ((ret = section_list_rw_unlock(p_section)) < 0)
400                            {
401                                    log_error("section_list_rw_unlock(sid = %d) error\n", p_section->sid);
402                                    break;
403                            }
404                    }
405    
406                    if ((p_section = section_list_find_by_sid(p_article->sid)) == NULL)
407                    {
408                            log_error("section_list_find_by_sid(%d) error: unknown section, try reloading section config\n", p_article->sid);
409                            ret = ERR_UNKNOWN_SECTION; // Unknown section found
410                            break;
411                    }
412    
413                    // acquire lock of current section if different from last one
414                    if (p_article->sid != last_sid)
415                    {
416                            if ((ret = section_list_rw_lock(p_section)) < 0)
417                            {
418                                    log_error("section_list_rw_lock(sid = 0) error\n");
419                                    break;
420                            }
421                    }
422    
423                    last_sid = p_article->sid;
424    
425                    switch (row[2][0])
426                    {
427                    case 'A': // Add article
428                            log_error("Operation type=A should not be found\n");
429                            break;
430                    case 'D': // Delete article
431                    case 'X': // Delete article by Admin
432                            p_article->visible = 0;
433                            if (p_article->tid == 0)
434                            {
435                                    // Set articles in the topic to be invisible
436                                    do
437                                    {
438                                            p_article = p_article->p_topic_next;
439                                            p_article->visible = 0;
440                                    } while (p_article->tid != 0);
441                            }
442                            break;
443                    case 'S': // Restore article
444                            p_article->visible = 1;
445                            break;
446                    case 'L': // Lock article
447                            p_article->lock = 1;
448                            break;
449                    case 'U': // Unlock article
450                            p_article->lock = 0;
451                            break;
452                    case 'M': // Modify article
453                            log_error("Operation type=M should not be found\n");
454                            break;
455                    case 'T': // Move article
456                            snprintf(sql, sizeof(sql),
457                                             "SELECT SID FROM bbs WHERE AID = %d",
458                                             p_article->aid);
459    
460                            if (mysql_query(db, sql) != 0)
461                            {
462                                    log_error("Query article error: %s\n", mysql_error(db));
463                                    ret = -3;
464                                    break;
465                            }
466                            if ((rs2 = mysql_store_result(db)) == NULL)
467                            {
468                                    log_error("Get article data failed\n");
469                                    ret = -3;
470                                    break;
471                            }
472                            if ((row2 = mysql_fetch_row(rs2)))
473                            {
474                                    sid_dest = atoi(row2[0]);
475                            }
476                            else
477                            {
478                                    sid_dest = 0;
479                                    ret = -4;
480                            }
481                            mysql_free_result(rs2);
482    
483                            if (sid_dest > 0 && sid_dest != p_article->sid)
484                            {
485                                    p_section_dest = section_list_find_by_sid(sid_dest);
486                                    if (p_section_dest == NULL)
487                                    {
488                                            ret = ERR_UNKNOWN_SECTION;
489                                            break;
490                                    }
491                                    // Move topic
492                                    if ((ret = section_list_move_topic(p_section, p_section_dest, p_article->aid)) < 0)
493                                    {
494                                            break;
495                                    }
496                            }
497                            break;
498                    case 'E': // Set article as excerption
499                            p_article->excerption = 1;
500                            break;
501                    case 'O': // Unset article as excerption
502                            p_article->excerption = 0;
503                            break;
504                    case 'F': // Set article on top
505                            p_article->ontop = 1;
506                            break;
507                    case 'V': // Unset article on top
508                            p_article->ontop = 0;
509                            break;
510                    case 'Z': // Set article as trnasship
511                            p_article->transship = 1;
512                            break;
513                    default:
514                            // log_error("Operation type=%s unknown, mid=%s\n", row[2], row[0]);
515                            break;
516                    }
517    
518                    if (ret < 0)
519                    {
520                            break;
521                    }
522    
523                    // Update MID with last successfully proceeded article_op_log
524                    last_article_op_log_mid = atoi(row[0]);
525            }
526    
527            // release lock of last section
528            if (last_sid != 0)
529            {
530                    if ((ret = section_list_rw_unlock(p_section)) < 0)
531                    {
532                            log_error("section_list_rw_unlock(sid = %d) error\n", p_section->sid);
533                    }
534            }
535    
536            mysql_free_result(rs);
537    
538            mysql_close(db);
539    
540            return ret;
541    }
542    
543  int section_list_loader_launch(void)  int section_list_loader_launch(void)
544  {  {
545          int pid;          int pid;
# Line 300  int section_list_loader_launch(void) Line 547  int section_list_loader_launch(void)
547          int32_t last_aid;          int32_t last_aid;
548          int article_count;          int article_count;
549          int load_count;          int load_count;
550            int last_mid;
551          int i;          int i;
552    
553          if (section_list_loader_pid != 0)          if (section_list_loader_pid != 0)
# Line 362  int section_list_loader_launch(void) Line 610  int section_list_loader_launch(void)
610                                  SYS_section_list_reload = 1; // Force reload section_list                                  SYS_section_list_reload = 1; // Force reload section_list
611                          }                          }
612                  }                  }
613                  else  
614                    load_count = article_block_article_count() - article_count;
615    
616                    if (load_count > 0)
617                  {                  {
618                          load_count = article_block_article_count() - article_count;                          log_std("Incrementally load %d articles, last_aid = %d\n", load_count, article_block_last_aid());
619                    }
620    
621                          if (load_count > 0)                  if (SYS_section_list_reload)
622                          {                  {
623                                  log_std("Incrementally load %d articles, last_aid = %d\n", load_count, article_block_last_aid());                          continue;
624                          }                  }
625    
626                          for (i = 0; i < SECTION_LIST_LOAD_INTERVAL && !SYS_server_exit && !SYS_section_list_reload; i++)                  // Load article_op log
627                    last_mid = last_article_op_log_mid;
628    
629                    if ((ret = apply_article_op_log_from_db()) < 0)
630                    {
631                            log_error("apply_article_op_log_from_db() error\n");
632    
633                            if (ret == ERR_UNKNOWN_SECTION)
634                          {                          {
635                                  sleep(1);                                  SYS_section_list_reload = 1; // Force reload section_list
636                          }                          }
637                  }                  }
638    
639                    if (last_article_op_log_mid > last_mid)
640                    {
641                            log_std("Proceeded %d article logs, last_mid = %d\n", last_article_op_log_mid - last_mid, last_article_op_log_mid);
642                    }
643    
644                    if (SYS_section_list_reload)
645                    {
646                            continue;
647                    }
648    
649                    for (i = 0; i < SECTION_LIST_LOAD_INTERVAL && !SYS_server_exit && !SYS_section_list_reload; i++)
650                    {
651                            sleep(1);
652                    }
653          }          }
654    
655          // Child process exit          // Child process exit


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1