/[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.7 by sysadm, Tue May 27 12:24: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                                    // acquire lock of dest section
492                                    if ((ret = section_list_rw_lock(p_section_dest)) < 0)
493                                    {
494                                            log_error("section_list_rw_lock(sid = %d) error\n", p_section_dest);
495                                            break;
496                                    }
497                                    // Move topic
498                                    if ((ret = section_list_move_topic(p_section, p_section_dest, p_article->aid)) < 0)
499                                    {
500                                            log_error("section_list_move_topic(src_sid=%d, dest_sid=%d, aid=%d) error (%d), retry in the next loop\n",
501                                                              p_section->sid, p_section_dest->sid, p_article->aid, ret);
502                                    }
503                                    // release lock of dest section
504                                    if (section_list_rw_unlock(p_section_dest) < 0)
505                                    {
506                                            log_error("section_list_rw_unlock(sid = %d) error\n", p_section_dest);
507                                            ret = -1;
508                                    }
509                            }
510                            break;
511                    case 'E': // Set article as excerption
512                            p_article->excerption = 1;
513                            break;
514                    case 'O': // Unset article as excerption
515                            p_article->excerption = 0;
516                            break;
517                    case 'F': // Set article on top
518                            p_article->ontop = 1;
519                            break;
520                    case 'V': // Unset article on top
521                            p_article->ontop = 0;
522                            break;
523                    case 'Z': // Set article as trnasship
524                            p_article->transship = 1;
525                            break;
526                    default:
527                            // log_error("Operation type=%s unknown, mid=%s\n", row[2], row[0]);
528                            break;
529                    }
530    
531                    if (ret < 0)
532                    {
533                            break;
534                    }
535    
536                    // Update MID with last successfully proceeded article_op_log
537                    last_article_op_log_mid = atoi(row[0]);
538            }
539    
540            // release lock of last section
541            if (last_sid != 0)
542            {
543                    if ((ret = section_list_rw_unlock(p_section)) < 0)
544                    {
545                            log_error("section_list_rw_unlock(sid = %d) error\n", p_section->sid);
546                    }
547            }
548    
549            mysql_free_result(rs);
550    
551            mysql_close(db);
552    
553            return ret;
554    }
555    
556  int section_list_loader_launch(void)  int section_list_loader_launch(void)
557  {  {
558          int pid;          int pid;
# Line 300  int section_list_loader_launch(void) Line 560  int section_list_loader_launch(void)
560          int32_t last_aid;          int32_t last_aid;
561          int article_count;          int article_count;
562          int load_count;          int load_count;
563            int last_mid;
564          int i;          int i;
565    
566          if (section_list_loader_pid != 0)          if (section_list_loader_pid != 0)
# Line 362  int section_list_loader_launch(void) Line 623  int section_list_loader_launch(void)
623                                  SYS_section_list_reload = 1; // Force reload section_list                                  SYS_section_list_reload = 1; // Force reload section_list
624                          }                          }
625                  }                  }
626                  else  
627                    load_count = article_block_article_count() - article_count;
628    
629                    if (load_count > 0)
630                  {                  {
631                          load_count = article_block_article_count() - article_count;                          log_std("Incrementally load %d articles, last_aid = %d\n", load_count, article_block_last_aid());
632                    }
633    
634                          if (load_count > 0)                  if (SYS_section_list_reload)
635                          {                  {
636                                  log_std("Incrementally load %d articles, last_aid = %d\n", load_count, article_block_last_aid());                          continue;
637                          }                  }
638    
639                          for (i = 0; i < SECTION_LIST_LOAD_INTERVAL && !SYS_server_exit && !SYS_section_list_reload; i++)                  // Load article_op log
640                    last_mid = last_article_op_log_mid;
641    
642                    if ((ret = apply_article_op_log_from_db()) < 0)
643                    {
644                            log_error("apply_article_op_log_from_db() error\n");
645    
646                            if (ret == ERR_UNKNOWN_SECTION)
647                          {                          {
648                                  sleep(1);                                  SYS_section_list_reload = 1; // Force reload section_list
649                          }                          }
650                  }                  }
651    
652                    if (last_article_op_log_mid > last_mid)
653                    {
654                            log_std("Proceeded %d article logs, last_mid = %d\n", last_article_op_log_mid - last_mid, last_article_op_log_mid);
655                    }
656    
657                    if (SYS_section_list_reload)
658                    {
659                            continue;
660                    }
661    
662                    for (i = 0; i < SECTION_LIST_LOAD_INTERVAL && !SYS_server_exit && !SYS_section_list_reload; i++)
663                    {
664                            sleep(1);
665                    }
666          }          }
667    
668          // Child process exit          // Child process exit
# Line 411  int section_list_loader_reload(void) Line 698  int section_list_loader_reload(void)
698    
699          return 0;          return 0;
700  }  }
701    
702    int query_section_articles(SECTION_LIST *p_section, int32_t page_id, ARTICLE *p_articles[], int32_t *p_article_count)
703    {
704            ARTICLE *p_article;
705            ARTICLE *p_next_page_first_article;
706            int ret = 0;
707    
708            if (p_section == NULL || p_articles == NULL || p_article_count == NULL)
709            {
710                    log_error("query_section_articles() NULL pointer error\n");
711                    return -1;
712            }
713    
714            // acquire lock of section
715            if ((ret = section_list_rd_lock(p_section)) < 0)
716            {
717                    log_error("section_list_rd_lock(sid = %d) error\n", p_section->sid);
718                    return -2;
719            }
720    
721            if (page_id >= p_section->page_count)
722            {
723                    page_id = p_section->page_count - 1;
724            }
725    
726            if (page_id < 0)
727            {
728                    ret = -3;
729            }
730            else
731            {
732                    ret = page_id;
733                    p_article = p_section->p_page_first_article[page_id];
734                    p_next_page_first_article =
735                            (page_id == p_section->page_count - 1 ? p_section->p_article_head : p_section->p_page_first_article[page_id + 1]);
736                    *p_article_count = 0;
737    
738                    do
739                    {
740                            if (p_article->visible)
741                            {
742                                    p_articles[*p_article_count] = p_article;
743                                    (*p_article_count)++;
744                            }
745                            p_article = p_article->p_next;
746                    } while (p_article != p_next_page_first_article && (*p_article_count) <= BBS_article_limit_per_page);
747            }
748    
749            // release lock of section
750            if ((ret = section_list_rd_unlock(p_section)) < 0)
751            {
752                    log_error("section_list_rd_unlock(sid = %d) error\n", p_section->sid);
753                    ret = -2;
754            }
755    
756            return ret;
757    }


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

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