Data.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import {
  2. createContext,
  3. useCallback,
  4. useContext,
  5. useEffect,
  6. useState,
  7. useRef,
  8. } from 'react';
  9. import { io, Socket } from 'socket.io-client';
  10. import { authContext } from '@/context';
  11. import { url, Collection, MilvusService, DatabaseService } from '@/http';
  12. import { checkIndexBuilding, checkLoading } from '@/utils';
  13. import { DataContextType } from './Types';
  14. import { WS_EVENTS, WS_EVENTS_TYPE } from '@server/utils/Const';
  15. import { LAST_TIME_DATABASE } from '@/consts';
  16. export const dataContext = createContext<DataContextType>({
  17. loading: false,
  18. collections: [],
  19. setCollections: () => {},
  20. database: 'default',
  21. setDatabase: () => {},
  22. databases: [],
  23. setDatabaseList: () => {},
  24. fetchDatabases: async () => {},
  25. fetchCollections: async () => {},
  26. });
  27. const { Provider } = dataContext;
  28. export const DataProvider = (props: { children: React.ReactNode }) => {
  29. // local data state
  30. const [collections, setCollections] = useState<Collection[]>([]);
  31. const [connected, setConnected] = useState(false);
  32. const [loading, setLoading] = useState(false);
  33. const [database, setDatabase] = useState<string>(
  34. window.localStorage.getItem(LAST_TIME_DATABASE) || 'default'
  35. );
  36. const [databases, setDatabases] = useState<string[]>(['default']);
  37. // auth context
  38. const { isAuth, clientId } = useContext(authContext);
  39. // socket ref
  40. const socket = useRef<Socket | null>(null);
  41. // socket callback
  42. const socketCallBack = useCallback(
  43. (data: any) => {
  44. const collections: Collection[] = data.map((v: any) => new Collection(v));
  45. const hasLoadingOrBuildingCollection = collections.some(
  46. v => checkLoading(v) || checkIndexBuilding(v)
  47. );
  48. setCollections(collections);
  49. // If no collection is building index or loading collection
  50. // stop server cron job
  51. if (!hasLoadingOrBuildingCollection) {
  52. MilvusService.triggerCron({
  53. name: WS_EVENTS.COLLECTION,
  54. type: WS_EVENTS_TYPE.STOP,
  55. });
  56. }
  57. },
  58. [database]
  59. );
  60. // http fetch collection
  61. const fetchCollections = async () => {
  62. try {
  63. setLoading(true);
  64. const res = await Collection.getCollections();
  65. setCollections(res);
  66. setLoading(false);
  67. } catch (error) {
  68. console.error(error);
  69. } finally {
  70. setLoading(false);
  71. }
  72. };
  73. const fetchDatabases = async () => {
  74. const res = await DatabaseService.getDatabases();
  75. setDatabases(res.db_names);
  76. };
  77. useEffect(() => {
  78. if (isAuth) {
  79. // fetch db
  80. fetchDatabases();
  81. // connect to socket server
  82. socket.current = io(url as string);
  83. // register client
  84. socket.current.emit(WS_EVENTS.REGISTER, clientId);
  85. socket.current.on('connect', function () {
  86. console.log('--- ws connected ---', clientId);
  87. setConnected(true);
  88. });
  89. socket.current?.on(WS_EVENTS.COLLECTION, socketCallBack);
  90. } else {
  91. socket.current?.disconnect();
  92. // clear collections
  93. setCollections([]);
  94. // clear database
  95. setDatabases(['default']);
  96. // set connected to false
  97. setConnected(false);
  98. }
  99. }, [isAuth]);
  100. useEffect(() => {
  101. if (connected) {
  102. // clear data
  103. setCollections([]);
  104. // remove all listeners
  105. socket.current?.offAny();
  106. // listen to collection event
  107. socket.current?.on(WS_EVENTS.COLLECTION, socketCallBack);
  108. // get data
  109. fetchCollections();
  110. }
  111. }, [socketCallBack, connected]);
  112. return (
  113. <Provider
  114. value={{
  115. loading,
  116. collections,
  117. setCollections,
  118. database,
  119. databases,
  120. setDatabase,
  121. setDatabaseList: setDatabases,
  122. fetchDatabases,
  123. fetchCollections,
  124. }}
  125. >
  126. {props.children}
  127. </Provider>
  128. );
  129. };