├── .asf.yaml ├── LICENSE ├── README.md ├── agent └── src │ └── c │ ├── Makefile │ ├── common │ ├── fsof_global.h │ ├── fsof_url.c │ ├── fsof_url.h │ ├── fsof_util.c │ ├── fsof_util.h │ ├── strmap.c │ └── strmap.h │ ├── include │ ├── hiredis │ │ ├── adapters │ │ │ ├── ae.h │ │ │ ├── glib.h │ │ │ ├── ivykis.h │ │ │ ├── libev.h │ │ │ ├── libevent.h │ │ │ ├── libuv.h │ │ │ ├── macosx.h │ │ │ └── qt.h │ │ ├── async.h │ │ ├── hiredis.h │ │ ├── read.h │ │ └── sds.h │ └── zlog.h │ ├── lib │ ├── libhiredis.a │ └── libzlog.a │ ├── release │ ├── agent │ ├── agent_log.conf │ ├── agent_server │ ├── protect_agent_server.sh │ └── start_agent_server.sh │ ├── service │ ├── fsof_log.c │ ├── fsof_log.h │ ├── fsof_mq.c │ ├── fsof_mq.h │ ├── fsof_redis.c │ ├── fsof_redis.h │ ├── fsof_zookeeper.c │ ├── fsof_zookeeper.h │ ├── mt_array.c │ └── mt_array.h │ └── src │ └── fsof_main.c ├── api └── FSOFApi.php ├── arch.png ├── bin ├── app_admin.php └── restartall.sh ├── common ├── BootStrap.php ├── FrameAutoLoader.php ├── config │ ├── FSOFCommonUtil.php │ ├── FSOFConfigManager.php │ ├── FSOFConfigUtil.php │ └── FSOFConstants.php ├── file │ ├── FSOFRedis.php │ └── FileSystemUtil.php ├── log │ └── FSOFSystemUtil.php ├── protocol │ └── fsof │ │ ├── DubboParser.php │ │ ├── DubboRequest.php │ │ └── DubboResponse.php └── url │ └── FSOFUrl.php ├── composer.json ├── config ├── app │ └── conf │ │ ├── dev │ │ └── provider │ │ │ └── demo-provider.deploy │ │ ├── gray │ │ └── provider │ │ │ └── example.deploy │ │ ├── pre │ │ └── provider │ │ │ └── example.deploy │ │ └── pro │ │ └── provider │ │ └── example.deploy └── global │ └── conf │ └── fsof.ini ├── consumer ├── ConsumerException.php ├── FSOFConsumer.php ├── FrameAutoLoader.php ├── Type.php ├── client │ ├── FSOFClient4Linux.php │ └── IFSOFClient.php ├── fsof │ └── FSOFProcessor.php └── proxy │ ├── Proxy.php │ └── ProxyFactory.php ├── demo ├── demo-consumer │ ├── config │ │ └── log4php.xml │ ├── consumer │ │ └── demo-consumer.consumer │ └── server │ │ └── Consumer.php └── demo-provider │ ├── BootStrap.php │ ├── config │ └── log4php.xml │ ├── provider │ └── demo-provider.provider │ └── server │ └── DemoServiceImpl.php ├── provider ├── FSOFProvider.php ├── FrameAutoLoader.php ├── common │ └── Console.php ├── core │ ├── app │ │ ├── AppAutoLoader.php │ │ ├── AppContext.php │ │ └── AppLauncher.php │ ├── protocol │ │ ├── BaseProtocol.php │ │ ├── BufferedProtocol.php │ │ └── IProtocol.php │ └── server │ │ ├── BaseServer.php │ │ ├── FSOFRegistry.php │ │ ├── IServer.php │ │ └── TcpServer.php ├── fsof │ └── FSOFProtocol.php ├── monitor │ ├── AppMonitor.php │ ├── OverloadMonitor.php │ └── ServiceMonitor.php └── shell │ └── StartUp.php └── registry ├── BootStrap.php ├── FrameAutoLoader.php └── automatic ├── ConsumerProxy.php ├── RegistryService.php ├── RegistryServiceFactory.php └── ZookeeperClient.php /.asf.yaml: -------------------------------------------------------------------------------- 1 | notifications: 2 | commits: commits@dubbo.apache.org 3 | issues: notifications@dubbo.apache.org 4 | pullrequests: notifications@dubbo.apache.org 5 | jira_options: link label link label 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## php framework for apache dubbo 2 | 3 | 4 | dubbo-php-framework is a RPC communication framework for PHP language. It is fully compatible with Dubbo protocol, and can be used as provider terminal and consumer terminal simultaneously. Using zookeeper for service registration discovery, and using fastjson and hessian for Serialization. 5 | 6 | ![image](https://github.com/apache/dubbo-php-framework/blob/master/arch.png) 7 | 8 | ## Introduction 9 | - php provider runs in multiple processes. The worker process is used to process specific business, the manager process controls the lifecycle of the worker process, and the master process processes the network IO. 10 | - Agent monitors the change of provider address information in registry and synchronizes them to local redis for all php consumers on the machine to share. 11 | - php consumer、redis and agent are deployed on all consumer machines and communicate with each other on unix socket. 12 | - provider_admin is deployed on all provider machines to control the lifecycle of all php providers on that machine. 13 | 14 | Quick start (Chinese) 15 | Installation guide (Chinese) 16 | Configuration guide (Chinese) 17 | 18 | 19 | -------------------------------------------------------------------------------- /agent/src/c/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = release/agent 2 | CFLAGS = -g -Wall -lpthread -lzookeeper_mt -L./lib -lhiredis -lzlog -I./include 3 | CC = gcc 4 | $(TARGET):service/fsof_mq.c src/fsof_main.c service/fsof_zookeeper.c common/strmap.c service/fsof_redis.c service/fsof_log.c common/fsof_url.c common/fsof_util.c service/mt_array.c 5 | $(CC) $^ $(CFLAGS) -o $@ 6 | .PHONY : clean 7 | clean: 8 | rm -f $(TARGET) 9 | -------------------------------------------------------------------------------- /agent/src/c/common/fsof_global.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef FSOF_GLOBAL_H 18 | #define FSOF_GLOBAL_H 19 | 20 | #define FSOF_ROOT_NAME "/dubbo" 21 | #define PROVIDER_NAME "/providers" 22 | #define PROVIDER_NODE_NAME "providers" 23 | #define CONSUMER_NAME "/consumers" 24 | #define ROUTERS_NAME "/routers" 25 | #define CONFIGUREATORS_NAME "/configurators" 26 | #define CONFIGUREATORS_NODE_NAME "configurators" 27 | #define FSOF_REDIS_CONFIGURATOR_KEY_NAME "override" 28 | 29 | #define ZOOKEEPER_HOST "127.0.0.1:2181" 30 | #define DEFAULT_MAP_COUNT (10) 31 | #define REDIS_UNIX_SOCK "/var/fsof/redis.sock" 32 | 33 | 34 | 35 | struct list { 36 | char *value; 37 | struct list *next; 38 | }; 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /agent/src/c/common/fsof_url.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "fsof_url.h" 18 | #include 19 | #include 20 | 21 | char * fsof_url_encode(char const *s, int len, int *new_length) { 22 | unsigned char const *from, *end; 23 | unsigned char c; 24 | from = (unsigned char const*)s; 25 | end = (unsigned char const*)s + len; 26 | unsigned char *to = (unsigned char *) malloc(3 * len + 1); 27 | unsigned char *start = to; 28 | 29 | unsigned char hexchars[] = "0123456789ABCDEF"; 30 | 31 | while (from < end) { 32 | c = *from++; 33 | 34 | if (c == ' ') { 35 | *to++ = '+'; 36 | } else if ((c < '0' && c != '-' && c != '.') 37 | ||(c < 'A' && c > '9') 38 | ||(c > 'Z' && c < 'a' && c != '_') 39 | ||(c > 'z')) { 40 | to[0] = '%'; 41 | to[1] = hexchars[c >> 4]; 42 | to[2] = hexchars[c & 15]; 43 | to += 3; 44 | } else { 45 | *to++ = c; 46 | } 47 | } 48 | 49 | *to = 0; 50 | if (new_length) { 51 | *new_length = to - start; 52 | } 53 | 54 | return (char *) start; 55 | } 56 | 57 | int fsof_url_decode(char *str, int len) 58 | { 59 | char *dest = str; 60 | char *data = str; 61 | int value; 62 | int c; 63 | 64 | while (len--) { 65 | if (*data == '+') { 66 | *dest = ' '; 67 | } 68 | else if (*data == '%' && len >= 2 && isxdigit((int) *(data + 1)) 69 | && isxdigit((int) *(data + 2))) { 70 | c = ((unsigned char *)(data+1))[0]; 71 | if (isupper(c)) { 72 | c = tolower(c); 73 | } 74 | 75 | value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16; 76 | c = ((unsigned char *)(data+1))[1]; 77 | if (isupper(c)) { 78 | c = tolower(c); 79 | } 80 | 81 | value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10; 82 | *dest = (char)value ; 83 | data += 2; 84 | len -= 2; 85 | } else { 86 | *dest = *data; 87 | } 88 | data++; 89 | dest++; 90 | } 91 | 92 | *dest = '\0'; 93 | return dest - str; 94 | 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /agent/src/c/common/fsof_url.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef FSOF_URL_H 18 | #define FSOF_URL_H 19 | #define URL_ENCODE_BUF_LEN (4 * 1024) 20 | int fsof_url_decode(char *str, int len); 21 | char * fsof_url_encode(char const *s, int len, int *new_length); 22 | #endif 23 | -------------------------------------------------------------------------------- /agent/src/c/common/fsof_util.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include 18 | #include 19 | #include "fsof_util.h" 20 | #include 21 | #include 22 | 23 | char * trim(char * src) { 24 | int i = 0; 25 | char *begin = src; 26 | while(src[i] != '\0') { 27 | if(src[i] != ' ') { 28 | break; 29 | }else { 30 | begin++; 31 | } 32 | i++; 33 | } 34 | 35 | for(i = strlen(src)-1; i >= 0; i--){ 36 | if(src[i] != ' '){ 37 | break; 38 | }else { 39 | src[i] = '\0'; 40 | } 41 | } 42 | 43 | return begin; 44 | } 45 | 46 | char *get_ini_key_string(char *title,char *key,char *filename) { 47 | FILE *fp; 48 | char szLine[1024]; 49 | static char tmpstr[1024]; 50 | char *ret_str = NULL; 51 | int rtnval; 52 | int i = 0; 53 | int flag = 0; 54 | char *tmp; 55 | 56 | if((fp = fopen(filename, "r")) == NULL) 57 | { 58 | printf("have no such file \n"); 59 | return ""; 60 | } 61 | 62 | while(!feof(fp)) 63 | { 64 | rtnval = fgetc(fp); 65 | if(rtnval == EOF) 66 | { 67 | break; 68 | } 69 | else 70 | { 71 | szLine[i++] = rtnval; 72 | } 73 | if(rtnval == '\n') 74 | { 75 | szLine[--i] = '\0'; 76 | i = 0; 77 | tmp = strchr(szLine, '='); 78 | 79 | if(( tmp != NULL )&&(flag == 1)) { 80 | if(strstr(szLine,key)!=NULL) 81 | { 82 | if ('#' == szLine[0]) 83 | { 84 | } 85 | else if ( '/' == szLine[0] && '/' == szLine[1] ) 86 | { 87 | 88 | } 89 | else 90 | { 91 | strcpy(tmpstr,tmp+1); 92 | fclose(fp); 93 | ret_str = trim(tmpstr); 94 | return ret_str; 95 | } 96 | } 97 | } 98 | else { 99 | strcpy(tmpstr,"["); 100 | strcat(tmpstr,title); 101 | strcat(tmpstr,"]"); 102 | if( strncmp(tmpstr,szLine,strlen(tmpstr)) == 0 ) 103 | { 104 | flag = 1; 105 | } 106 | } 107 | } 108 | } 109 | 110 | fclose(fp); 111 | return ""; 112 | 113 | } 114 | 115 | 116 | int get_current_path(char buf[],char *pFileName,int depth) { 117 | char pidfile[64] = {0}; 118 | char *p = NULL; 119 | int bytes = 0; 120 | int fd = 0; 121 | int cur_dp = 0; 122 | 123 | sprintf(pidfile, "/proc/%d/cmdline", getpid()); 124 | fd = open(pidfile, O_RDONLY, 0); 125 | bytes = read(fd, buf, 256); 126 | close(fd); 127 | 128 | p = &buf[strlen(buf)]; 129 | _AGAIN: 130 | while ('/' != *p) { 131 | *p = '\0'; 132 | if ((p - buf) == 0) { 133 | return 1; //path now null,can't get depth dir 134 | } 135 | p--; 136 | } 137 | 138 | cur_dp++; 139 | if (cur_dp < depth) { 140 | p--; 141 | goto _AGAIN; 142 | } 143 | p++; 144 | 145 | memcpy(p,pFileName,strlen(pFileName)); 146 | p += strlen(pFileName); 147 | *p = '\0'; 148 | return 0; 149 | } 150 | -------------------------------------------------------------------------------- /agent/src/c/common/fsof_util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef FSOF_UTIL_H 18 | #define FSOF_UTIL_H 19 | 20 | #define MAX_CONFIG_PATH_LEN 260 21 | 22 | char *get_ini_key_string(char *title,char *key,char *filename); 23 | int get_current_path(char buf[],char *pFileName,int depth); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/ae.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011, Pieter Noordhuis 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __HIREDIS_AE_H__ 32 | #define __HIREDIS_AE_H__ 33 | #include 34 | #include 35 | #include "../hiredis.h" 36 | #include "../async.h" 37 | 38 | typedef struct redisAeEvents { 39 | redisAsyncContext *context; 40 | aeEventLoop *loop; 41 | int fd; 42 | int reading, writing; 43 | } redisAeEvents; 44 | 45 | static void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { 46 | ((void)el); ((void)fd); ((void)mask); 47 | 48 | redisAeEvents *e = (redisAeEvents*)privdata; 49 | redisAsyncHandleRead(e->context); 50 | } 51 | 52 | static void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { 53 | ((void)el); ((void)fd); ((void)mask); 54 | 55 | redisAeEvents *e = (redisAeEvents*)privdata; 56 | redisAsyncHandleWrite(e->context); 57 | } 58 | 59 | static void redisAeAddRead(void *privdata) { 60 | redisAeEvents *e = (redisAeEvents*)privdata; 61 | aeEventLoop *loop = e->loop; 62 | if (!e->reading) { 63 | e->reading = 1; 64 | aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); 65 | } 66 | } 67 | 68 | static void redisAeDelRead(void *privdata) { 69 | redisAeEvents *e = (redisAeEvents*)privdata; 70 | aeEventLoop *loop = e->loop; 71 | if (e->reading) { 72 | e->reading = 0; 73 | aeDeleteFileEvent(loop,e->fd,AE_READABLE); 74 | } 75 | } 76 | 77 | static void redisAeAddWrite(void *privdata) { 78 | redisAeEvents *e = (redisAeEvents*)privdata; 79 | aeEventLoop *loop = e->loop; 80 | if (!e->writing) { 81 | e->writing = 1; 82 | aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); 83 | } 84 | } 85 | 86 | static void redisAeDelWrite(void *privdata) { 87 | redisAeEvents *e = (redisAeEvents*)privdata; 88 | aeEventLoop *loop = e->loop; 89 | if (e->writing) { 90 | e->writing = 0; 91 | aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); 92 | } 93 | } 94 | 95 | static void redisAeCleanup(void *privdata) { 96 | redisAeEvents *e = (redisAeEvents*)privdata; 97 | redisAeDelRead(privdata); 98 | redisAeDelWrite(privdata); 99 | free(e); 100 | } 101 | 102 | static int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { 103 | redisContext *c = &(ac->c); 104 | redisAeEvents *e; 105 | 106 | /* Nothing should be attached when something is already attached */ 107 | if (ac->ev.data != NULL) 108 | return REDIS_ERR; 109 | 110 | /* Create container for context and r/w events */ 111 | e = (redisAeEvents*)malloc(sizeof(*e)); 112 | e->context = ac; 113 | e->loop = loop; 114 | e->fd = c->fd; 115 | e->reading = e->writing = 0; 116 | 117 | /* Register functions to start/stop listening for events */ 118 | ac->ev.addRead = redisAeAddRead; 119 | ac->ev.delRead = redisAeDelRead; 120 | ac->ev.addWrite = redisAeAddWrite; 121 | ac->ev.delWrite = redisAeDelWrite; 122 | ac->ev.cleanup = redisAeCleanup; 123 | ac->ev.data = e; 124 | 125 | return REDIS_OK; 126 | } 127 | #endif 128 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/glib.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef __HIREDIS_GLIB_H__ 18 | #define __HIREDIS_GLIB_H__ 19 | 20 | #include 21 | 22 | #include "../hiredis.h" 23 | #include "../async.h" 24 | 25 | typedef struct 26 | { 27 | GSource source; 28 | redisAsyncContext *ac; 29 | GPollFD poll_fd; 30 | } RedisSource; 31 | 32 | static void 33 | redis_source_add_read (gpointer data) 34 | { 35 | RedisSource *source = (RedisSource *)data; 36 | g_return_if_fail(source); 37 | source->poll_fd.events |= G_IO_IN; 38 | g_main_context_wakeup(g_source_get_context((GSource *)data)); 39 | } 40 | 41 | static void 42 | redis_source_del_read (gpointer data) 43 | { 44 | RedisSource *source = (RedisSource *)data; 45 | g_return_if_fail(source); 46 | source->poll_fd.events &= ~G_IO_IN; 47 | g_main_context_wakeup(g_source_get_context((GSource *)data)); 48 | } 49 | 50 | static void 51 | redis_source_add_write (gpointer data) 52 | { 53 | RedisSource *source = (RedisSource *)data; 54 | g_return_if_fail(source); 55 | source->poll_fd.events |= G_IO_OUT; 56 | g_main_context_wakeup(g_source_get_context((GSource *)data)); 57 | } 58 | 59 | static void 60 | redis_source_del_write (gpointer data) 61 | { 62 | RedisSource *source = (RedisSource *)data; 63 | g_return_if_fail(source); 64 | source->poll_fd.events &= ~G_IO_OUT; 65 | g_main_context_wakeup(g_source_get_context((GSource *)data)); 66 | } 67 | 68 | static void 69 | redis_source_cleanup (gpointer data) 70 | { 71 | RedisSource *source = (RedisSource *)data; 72 | 73 | g_return_if_fail(source); 74 | 75 | redis_source_del_read(source); 76 | redis_source_del_write(source); 77 | /* 78 | * It is not our responsibility to remove ourself from the 79 | * current main loop. However, we will remove the GPollFD. 80 | */ 81 | if (source->poll_fd.fd >= 0) { 82 | g_source_remove_poll((GSource *)data, &source->poll_fd); 83 | source->poll_fd.fd = -1; 84 | } 85 | } 86 | 87 | static gboolean 88 | redis_source_prepare (GSource *source, 89 | gint *timeout_) 90 | { 91 | RedisSource *redis = (RedisSource *)source; 92 | *timeout_ = -1; 93 | return !!(redis->poll_fd.events & redis->poll_fd.revents); 94 | } 95 | 96 | static gboolean 97 | redis_source_check (GSource *source) 98 | { 99 | RedisSource *redis = (RedisSource *)source; 100 | return !!(redis->poll_fd.events & redis->poll_fd.revents); 101 | } 102 | 103 | static gboolean 104 | redis_source_dispatch (GSource *source, 105 | GSourceFunc callback, 106 | gpointer user_data) 107 | { 108 | RedisSource *redis = (RedisSource *)source; 109 | 110 | if ((redis->poll_fd.revents & G_IO_OUT)) { 111 | redisAsyncHandleWrite(redis->ac); 112 | redis->poll_fd.revents &= ~G_IO_OUT; 113 | } 114 | 115 | if ((redis->poll_fd.revents & G_IO_IN)) { 116 | redisAsyncHandleRead(redis->ac); 117 | redis->poll_fd.revents &= ~G_IO_IN; 118 | } 119 | 120 | if (callback) { 121 | return callback(user_data); 122 | } 123 | 124 | return TRUE; 125 | } 126 | 127 | static void 128 | redis_source_finalize (GSource *source) 129 | { 130 | RedisSource *redis = (RedisSource *)source; 131 | 132 | if (redis->poll_fd.fd >= 0) { 133 | g_source_remove_poll(source, &redis->poll_fd); 134 | redis->poll_fd.fd = -1; 135 | } 136 | } 137 | 138 | static GSource * 139 | redis_source_new (redisAsyncContext *ac) 140 | { 141 | static GSourceFuncs source_funcs = { 142 | .prepare = redis_source_prepare, 143 | .check = redis_source_check, 144 | .dispatch = redis_source_dispatch, 145 | .finalize = redis_source_finalize, 146 | }; 147 | redisContext *c = &ac->c; 148 | RedisSource *source; 149 | 150 | g_return_val_if_fail(ac != NULL, NULL); 151 | 152 | source = (RedisSource *)g_source_new(&source_funcs, sizeof *source); 153 | source->ac = ac; 154 | source->poll_fd.fd = c->fd; 155 | source->poll_fd.events = 0; 156 | source->poll_fd.revents = 0; 157 | g_source_add_poll((GSource *)source, &source->poll_fd); 158 | 159 | ac->ev.addRead = redis_source_add_read; 160 | ac->ev.delRead = redis_source_del_read; 161 | ac->ev.addWrite = redis_source_add_write; 162 | ac->ev.delWrite = redis_source_del_write; 163 | ac->ev.cleanup = redis_source_cleanup; 164 | ac->ev.data = source; 165 | 166 | return (GSource *)source; 167 | } 168 | 169 | #endif /* __HIREDIS_GLIB_H__ */ 170 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/ivykis.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_IVYKIS_H__ 2 | #define __HIREDIS_IVYKIS_H__ 3 | #include 4 | #include "../hiredis.h" 5 | #include "../async.h" 6 | 7 | typedef struct redisIvykisEvents { 8 | redisAsyncContext *context; 9 | struct iv_fd fd; 10 | } redisIvykisEvents; 11 | 12 | static void redisIvykisReadEvent(void *arg) { 13 | redisAsyncContext *context = (redisAsyncContext *)arg; 14 | redisAsyncHandleRead(context); 15 | } 16 | 17 | static void redisIvykisWriteEvent(void *arg) { 18 | redisAsyncContext *context = (redisAsyncContext *)arg; 19 | redisAsyncHandleWrite(context); 20 | } 21 | 22 | static void redisIvykisAddRead(void *privdata) { 23 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 24 | iv_fd_set_handler_in(&e->fd, redisIvykisReadEvent); 25 | } 26 | 27 | static void redisIvykisDelRead(void *privdata) { 28 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 29 | iv_fd_set_handler_in(&e->fd, NULL); 30 | } 31 | 32 | static void redisIvykisAddWrite(void *privdata) { 33 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 34 | iv_fd_set_handler_out(&e->fd, redisIvykisWriteEvent); 35 | } 36 | 37 | static void redisIvykisDelWrite(void *privdata) { 38 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 39 | iv_fd_set_handler_out(&e->fd, NULL); 40 | } 41 | 42 | static void redisIvykisCleanup(void *privdata) { 43 | redisIvykisEvents *e = (redisIvykisEvents*)privdata; 44 | 45 | iv_fd_unregister(&e->fd); 46 | free(e); 47 | } 48 | 49 | static int redisIvykisAttach(redisAsyncContext *ac) { 50 | redisContext *c = &(ac->c); 51 | redisIvykisEvents *e; 52 | 53 | /* Nothing should be attached when something is already attached */ 54 | if (ac->ev.data != NULL) 55 | return REDIS_ERR; 56 | 57 | /* Create container for context and r/w events */ 58 | e = (redisIvykisEvents*)malloc(sizeof(*e)); 59 | e->context = ac; 60 | 61 | /* Register functions to start/stop listening for events */ 62 | ac->ev.addRead = redisIvykisAddRead; 63 | ac->ev.delRead = redisIvykisDelRead; 64 | ac->ev.addWrite = redisIvykisAddWrite; 65 | ac->ev.delWrite = redisIvykisDelWrite; 66 | ac->ev.cleanup = redisIvykisCleanup; 67 | ac->ev.data = e; 68 | 69 | /* Initialize and install read/write events */ 70 | IV_FD_INIT(&e->fd); 71 | e->fd.fd = c->fd; 72 | e->fd.handler_in = redisIvykisReadEvent; 73 | e->fd.handler_out = redisIvykisWriteEvent; 74 | e->fd.handler_err = NULL; 75 | e->fd.cookie = e->context; 76 | 77 | iv_fd_register(&e->fd); 78 | 79 | return REDIS_OK; 80 | } 81 | #endif 82 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/libev.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011, Pieter Noordhuis 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __HIREDIS_LIBEV_H__ 32 | #define __HIREDIS_LIBEV_H__ 33 | #include 34 | #include 35 | #include 36 | #include "../hiredis.h" 37 | #include "../async.h" 38 | 39 | typedef struct redisLibevEvents { 40 | redisAsyncContext *context; 41 | struct ev_loop *loop; 42 | int reading, writing; 43 | ev_io rev, wev; 44 | } redisLibevEvents; 45 | 46 | static void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { 47 | #if EV_MULTIPLICITY 48 | ((void)loop); 49 | #endif 50 | ((void)revents); 51 | 52 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; 53 | redisAsyncHandleRead(e->context); 54 | } 55 | 56 | static void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { 57 | #if EV_MULTIPLICITY 58 | ((void)loop); 59 | #endif 60 | ((void)revents); 61 | 62 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; 63 | redisAsyncHandleWrite(e->context); 64 | } 65 | 66 | static void redisLibevAddRead(void *privdata) { 67 | redisLibevEvents *e = (redisLibevEvents*)privdata; 68 | struct ev_loop *loop = e->loop; 69 | ((void)loop); 70 | if (!e->reading) { 71 | e->reading = 1; 72 | ev_io_start(EV_A_ &e->rev); 73 | } 74 | } 75 | 76 | static void redisLibevDelRead(void *privdata) { 77 | redisLibevEvents *e = (redisLibevEvents*)privdata; 78 | struct ev_loop *loop = e->loop; 79 | ((void)loop); 80 | if (e->reading) { 81 | e->reading = 0; 82 | ev_io_stop(EV_A_ &e->rev); 83 | } 84 | } 85 | 86 | static void redisLibevAddWrite(void *privdata) { 87 | redisLibevEvents *e = (redisLibevEvents*)privdata; 88 | struct ev_loop *loop = e->loop; 89 | ((void)loop); 90 | if (!e->writing) { 91 | e->writing = 1; 92 | ev_io_start(EV_A_ &e->wev); 93 | } 94 | } 95 | 96 | static void redisLibevDelWrite(void *privdata) { 97 | redisLibevEvents *e = (redisLibevEvents*)privdata; 98 | struct ev_loop *loop = e->loop; 99 | ((void)loop); 100 | if (e->writing) { 101 | e->writing = 0; 102 | ev_io_stop(EV_A_ &e->wev); 103 | } 104 | } 105 | 106 | static void redisLibevCleanup(void *privdata) { 107 | redisLibevEvents *e = (redisLibevEvents*)privdata; 108 | redisLibevDelRead(privdata); 109 | redisLibevDelWrite(privdata); 110 | free(e); 111 | } 112 | 113 | static int redisLibevAttach(EV_P_ redisAsyncContext *ac) { 114 | redisContext *c = &(ac->c); 115 | redisLibevEvents *e; 116 | 117 | /* Nothing should be attached when something is already attached */ 118 | if (ac->ev.data != NULL) 119 | return REDIS_ERR; 120 | 121 | /* Create container for context and r/w events */ 122 | e = (redisLibevEvents*)malloc(sizeof(*e)); 123 | e->context = ac; 124 | #if EV_MULTIPLICITY 125 | e->loop = loop; 126 | #else 127 | e->loop = NULL; 128 | #endif 129 | e->reading = e->writing = 0; 130 | e->rev.data = e; 131 | e->wev.data = e; 132 | 133 | /* Register functions to start/stop listening for events */ 134 | ac->ev.addRead = redisLibevAddRead; 135 | ac->ev.delRead = redisLibevDelRead; 136 | ac->ev.addWrite = redisLibevAddWrite; 137 | ac->ev.delWrite = redisLibevDelWrite; 138 | ac->ev.cleanup = redisLibevCleanup; 139 | ac->ev.data = e; 140 | 141 | /* Initialize read/write events */ 142 | ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); 143 | ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); 144 | return REDIS_OK; 145 | } 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/libevent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011, Pieter Noordhuis 3 | * 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __HIREDIS_LIBEVENT_H__ 32 | #define __HIREDIS_LIBEVENT_H__ 33 | #include 34 | #include "../hiredis.h" 35 | #include "../async.h" 36 | 37 | typedef struct redisLibeventEvents { 38 | redisAsyncContext *context; 39 | struct event rev, wev; 40 | } redisLibeventEvents; 41 | 42 | static void redisLibeventReadEvent(int fd, short event, void *arg) { 43 | ((void)fd); ((void)event); 44 | redisLibeventEvents *e = (redisLibeventEvents*)arg; 45 | redisAsyncHandleRead(e->context); 46 | } 47 | 48 | static void redisLibeventWriteEvent(int fd, short event, void *arg) { 49 | ((void)fd); ((void)event); 50 | redisLibeventEvents *e = (redisLibeventEvents*)arg; 51 | redisAsyncHandleWrite(e->context); 52 | } 53 | 54 | static void redisLibeventAddRead(void *privdata) { 55 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 56 | event_add(&e->rev,NULL); 57 | } 58 | 59 | static void redisLibeventDelRead(void *privdata) { 60 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 61 | event_del(&e->rev); 62 | } 63 | 64 | static void redisLibeventAddWrite(void *privdata) { 65 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 66 | event_add(&e->wev,NULL); 67 | } 68 | 69 | static void redisLibeventDelWrite(void *privdata) { 70 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 71 | event_del(&e->wev); 72 | } 73 | 74 | static void redisLibeventCleanup(void *privdata) { 75 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 76 | event_del(&e->rev); 77 | event_del(&e->wev); 78 | free(e); 79 | } 80 | 81 | static int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { 82 | redisContext *c = &(ac->c); 83 | redisLibeventEvents *e; 84 | 85 | /* Nothing should be attached when something is already attached */ 86 | if (ac->ev.data != NULL) 87 | return REDIS_ERR; 88 | 89 | /* Create container for context and r/w events */ 90 | e = (redisLibeventEvents*)malloc(sizeof(*e)); 91 | e->context = ac; 92 | 93 | /* Register functions to start/stop listening for events */ 94 | ac->ev.addRead = redisLibeventAddRead; 95 | ac->ev.delRead = redisLibeventDelRead; 96 | ac->ev.addWrite = redisLibeventAddWrite; 97 | ac->ev.delWrite = redisLibeventDelWrite; 98 | ac->ev.cleanup = redisLibeventCleanup; 99 | ac->ev.data = e; 100 | 101 | /* Initialize and install read/write events */ 102 | event_set(&e->rev,c->fd,EV_READ,redisLibeventReadEvent,e); 103 | event_set(&e->wev,c->fd,EV_WRITE,redisLibeventWriteEvent,e); 104 | event_base_set(base,&e->rev); 105 | event_base_set(base,&e->wev); 106 | return REDIS_OK; 107 | } 108 | #endif 109 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/libuv.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_LIBUV_H__ 2 | #define __HIREDIS_LIBUV_H__ 3 | #include 4 | #include 5 | #include "../hiredis.h" 6 | #include "../async.h" 7 | #include 8 | 9 | typedef struct redisLibuvEvents { 10 | redisAsyncContext* context; 11 | uv_poll_t handle; 12 | int events; 13 | } redisLibuvEvents; 14 | 15 | 16 | static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { 17 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; 18 | 19 | if (status != 0) { 20 | return; 21 | } 22 | 23 | if (events & UV_READABLE) { 24 | redisAsyncHandleRead(p->context); 25 | } 26 | if (events & UV_WRITABLE) { 27 | redisAsyncHandleWrite(p->context); 28 | } 29 | } 30 | 31 | 32 | static void redisLibuvAddRead(void *privdata) { 33 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 34 | 35 | p->events |= UV_READABLE; 36 | 37 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 38 | } 39 | 40 | 41 | static void redisLibuvDelRead(void *privdata) { 42 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 43 | 44 | p->events &= ~UV_READABLE; 45 | 46 | if (p->events) { 47 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 48 | } else { 49 | uv_poll_stop(&p->handle); 50 | } 51 | } 52 | 53 | 54 | static void redisLibuvAddWrite(void *privdata) { 55 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 56 | 57 | p->events |= UV_WRITABLE; 58 | 59 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 60 | } 61 | 62 | 63 | static void redisLibuvDelWrite(void *privdata) { 64 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 65 | 66 | p->events &= ~UV_WRITABLE; 67 | 68 | if (p->events) { 69 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 70 | } else { 71 | uv_poll_stop(&p->handle); 72 | } 73 | } 74 | 75 | 76 | static void on_close(uv_handle_t* handle) { 77 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; 78 | 79 | free(p); 80 | } 81 | 82 | 83 | static void redisLibuvCleanup(void *privdata) { 84 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 85 | 86 | uv_close((uv_handle_t*)&p->handle, on_close); 87 | } 88 | 89 | 90 | static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { 91 | redisContext *c = &(ac->c); 92 | 93 | if (ac->ev.data != NULL) { 94 | return REDIS_ERR; 95 | } 96 | 97 | ac->ev.addRead = redisLibuvAddRead; 98 | ac->ev.delRead = redisLibuvDelRead; 99 | ac->ev.addWrite = redisLibuvAddWrite; 100 | ac->ev.delWrite = redisLibuvDelWrite; 101 | ac->ev.cleanup = redisLibuvCleanup; 102 | 103 | redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p)); 104 | 105 | if (!p) { 106 | return REDIS_ERR; 107 | } 108 | 109 | memset(p, 0, sizeof(*p)); 110 | 111 | if (uv_poll_init(loop, &p->handle, c->fd) != 0) { 112 | return REDIS_ERR; 113 | } 114 | 115 | ac->ev.data = p; 116 | p->handle.data = p; 117 | p->context = ac; 118 | 119 | return REDIS_OK; 120 | } 121 | #endif 122 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/macosx.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Дмитрий Бахвалов on 13.07.15. 3 | // Copyright (c) 2015 Dmitry Bakhvalov. All rights reserved. 4 | // 5 | 6 | #ifndef __HIREDIS_MACOSX_H__ 7 | #define __HIREDIS_MACOSX_H__ 8 | 9 | #include 10 | 11 | #include "../hiredis.h" 12 | #include "../async.h" 13 | 14 | typedef struct { 15 | redisAsyncContext *context; 16 | CFSocketRef socketRef; 17 | CFRunLoopSourceRef sourceRef; 18 | } RedisRunLoop; 19 | 20 | static int freeRedisRunLoop(RedisRunLoop* redisRunLoop) { 21 | if( redisRunLoop != NULL ) { 22 | if( redisRunLoop->sourceRef != NULL ) { 23 | CFRunLoopSourceInvalidate(redisRunLoop->sourceRef); 24 | CFRelease(redisRunLoop->sourceRef); 25 | } 26 | if( redisRunLoop->socketRef != NULL ) { 27 | CFSocketInvalidate(redisRunLoop->socketRef); 28 | CFRelease(redisRunLoop->socketRef); 29 | } 30 | free(redisRunLoop); 31 | } 32 | return REDIS_ERR; 33 | } 34 | 35 | static void redisMacOSAddRead(void *privdata) { 36 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; 37 | CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); 38 | } 39 | 40 | static void redisMacOSDelRead(void *privdata) { 41 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; 42 | CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketReadCallBack); 43 | } 44 | 45 | static void redisMacOSAddWrite(void *privdata) { 46 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; 47 | CFSocketEnableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); 48 | } 49 | 50 | static void redisMacOSDelWrite(void *privdata) { 51 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; 52 | CFSocketDisableCallBacks(redisRunLoop->socketRef, kCFSocketWriteCallBack); 53 | } 54 | 55 | static void redisMacOSCleanup(void *privdata) { 56 | RedisRunLoop *redisRunLoop = (RedisRunLoop*)privdata; 57 | freeRedisRunLoop(redisRunLoop); 58 | } 59 | 60 | static void redisMacOSAsyncCallback(CFSocketRef __unused s, CFSocketCallBackType callbackType, CFDataRef __unused address, const void __unused *data, void *info) { 61 | redisAsyncContext* context = (redisAsyncContext*) info; 62 | 63 | switch (callbackType) { 64 | case kCFSocketReadCallBack: 65 | redisAsyncHandleRead(context); 66 | break; 67 | 68 | case kCFSocketWriteCallBack: 69 | redisAsyncHandleWrite(context); 70 | break; 71 | 72 | default: 73 | break; 74 | } 75 | } 76 | 77 | static int redisMacOSAttach(redisAsyncContext *redisAsyncCtx, CFRunLoopRef runLoop) { 78 | redisContext *redisCtx = &(redisAsyncCtx->c); 79 | 80 | /* Nothing should be attached when something is already attached */ 81 | if( redisAsyncCtx->ev.data != NULL ) return REDIS_ERR; 82 | 83 | RedisRunLoop* redisRunLoop = (RedisRunLoop*) calloc(1, sizeof(RedisRunLoop)); 84 | if( !redisRunLoop ) return REDIS_ERR; 85 | 86 | /* Setup redis stuff */ 87 | redisRunLoop->context = redisAsyncCtx; 88 | 89 | redisAsyncCtx->ev.addRead = redisMacOSAddRead; 90 | redisAsyncCtx->ev.delRead = redisMacOSDelRead; 91 | redisAsyncCtx->ev.addWrite = redisMacOSAddWrite; 92 | redisAsyncCtx->ev.delWrite = redisMacOSDelWrite; 93 | redisAsyncCtx->ev.cleanup = redisMacOSCleanup; 94 | redisAsyncCtx->ev.data = redisRunLoop; 95 | 96 | /* Initialize and install read/write events */ 97 | CFSocketContext socketCtx = { 0, redisAsyncCtx, NULL, NULL, NULL }; 98 | 99 | redisRunLoop->socketRef = CFSocketCreateWithNative(NULL, redisCtx->fd, 100 | kCFSocketReadCallBack | kCFSocketWriteCallBack, 101 | redisMacOSAsyncCallback, 102 | &socketCtx); 103 | if( !redisRunLoop->socketRef ) return freeRedisRunLoop(redisRunLoop); 104 | 105 | redisRunLoop->sourceRef = CFSocketCreateRunLoopSource(NULL, redisRunLoop->socketRef, 0); 106 | if( !redisRunLoop->sourceRef ) return freeRedisRunLoop(redisRunLoop); 107 | 108 | CFRunLoopAddSource(runLoop, redisRunLoop->sourceRef, kCFRunLoopDefaultMode); 109 | 110 | return REDIS_OK; 111 | } 112 | 113 | #endif 114 | 115 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/adapters/qt.h: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (C) 2014 Pietro Cerutti 3 | * 4 | * Redistribution and use in source and binary forms, with or without 5 | * modification, are permitted provided that the following conditions 6 | * are met: 7 | * 1. Redistributions of source code must retain the above copyright 8 | * notice, this list of conditions and the following disclaimer. 9 | * 2. Redistributions in binary form must reproduce the above copyright 10 | * notice, this list of conditions and the following disclaimer in the 11 | * documentation and/or other materials provided with the distribution. 12 | * 13 | * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 | * SUCH DAMAGE. 24 | */ 25 | 26 | #ifndef __HIREDIS_QT_H__ 27 | #define __HIREDIS_QT_H__ 28 | #include 29 | #include "../async.h" 30 | 31 | static void RedisQtAddRead(void *); 32 | static void RedisQtDelRead(void *); 33 | static void RedisQtAddWrite(void *); 34 | static void RedisQtDelWrite(void *); 35 | static void RedisQtCleanup(void *); 36 | 37 | class RedisQtAdapter : public QObject { 38 | 39 | Q_OBJECT 40 | 41 | friend 42 | void RedisQtAddRead(void * adapter) { 43 | RedisQtAdapter * a = static_cast(adapter); 44 | a->addRead(); 45 | } 46 | 47 | friend 48 | void RedisQtDelRead(void * adapter) { 49 | RedisQtAdapter * a = static_cast(adapter); 50 | a->delRead(); 51 | } 52 | 53 | friend 54 | void RedisQtAddWrite(void * adapter) { 55 | RedisQtAdapter * a = static_cast(adapter); 56 | a->addWrite(); 57 | } 58 | 59 | friend 60 | void RedisQtDelWrite(void * adapter) { 61 | RedisQtAdapter * a = static_cast(adapter); 62 | a->delWrite(); 63 | } 64 | 65 | friend 66 | void RedisQtCleanup(void * adapter) { 67 | RedisQtAdapter * a = static_cast(adapter); 68 | a->cleanup(); 69 | } 70 | 71 | public: 72 | RedisQtAdapter(QObject * parent = 0) 73 | : QObject(parent), m_ctx(0), m_read(0), m_write(0) { } 74 | 75 | ~RedisQtAdapter() { 76 | if (m_ctx != 0) { 77 | m_ctx->ev.data = NULL; 78 | } 79 | } 80 | 81 | int setContext(redisAsyncContext * ac) { 82 | if (ac->ev.data != NULL) { 83 | return REDIS_ERR; 84 | } 85 | m_ctx = ac; 86 | m_ctx->ev.data = this; 87 | m_ctx->ev.addRead = RedisQtAddRead; 88 | m_ctx->ev.delRead = RedisQtDelRead; 89 | m_ctx->ev.addWrite = RedisQtAddWrite; 90 | m_ctx->ev.delWrite = RedisQtDelWrite; 91 | m_ctx->ev.cleanup = RedisQtCleanup; 92 | return REDIS_OK; 93 | } 94 | 95 | private: 96 | void addRead() { 97 | if (m_read) return; 98 | m_read = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Read, 0); 99 | connect(m_read, SIGNAL(activated(int)), this, SLOT(read())); 100 | } 101 | 102 | void delRead() { 103 | if (!m_read) return; 104 | delete m_read; 105 | m_read = 0; 106 | } 107 | 108 | void addWrite() { 109 | if (m_write) return; 110 | m_write = new QSocketNotifier(m_ctx->c.fd, QSocketNotifier::Write, 0); 111 | connect(m_write, SIGNAL(activated(int)), this, SLOT(write())); 112 | } 113 | 114 | void delWrite() { 115 | if (!m_write) return; 116 | delete m_write; 117 | m_write = 0; 118 | } 119 | 120 | void cleanup() { 121 | delRead(); 122 | delWrite(); 123 | } 124 | 125 | private slots: 126 | void read() { redisAsyncHandleRead(m_ctx); } 127 | void write() { redisAsyncHandleWrite(m_ctx); } 128 | 129 | private: 130 | redisAsyncContext * m_ctx; 131 | QSocketNotifier * m_read; 132 | QSocketNotifier * m_write; 133 | }; 134 | 135 | #endif /* !__HIREDIS_QT_H__ */ 136 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/async.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2011, Salvatore Sanfilippo 3 | * Copyright (c) 2010-2011, Pieter Noordhuis 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | #ifndef __HIREDIS_ASYNC_H 33 | #define __HIREDIS_ASYNC_H 34 | #include "hiredis.h" 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | struct redisAsyncContext; /* need forward declaration of redisAsyncContext */ 41 | struct dict; /* dictionary header is included in async.c */ 42 | 43 | /* Reply callback prototype and container */ 44 | typedef void (redisCallbackFn)(struct redisAsyncContext*, void*, void*); 45 | typedef struct redisCallback { 46 | struct redisCallback *next; /* simple singly linked list */ 47 | redisCallbackFn *fn; 48 | void *privdata; 49 | } redisCallback; 50 | 51 | /* List of callbacks for either regular replies or pub/sub */ 52 | typedef struct redisCallbackList { 53 | redisCallback *head, *tail; 54 | } redisCallbackList; 55 | 56 | /* Connection callback prototypes */ 57 | typedef void (redisDisconnectCallback)(const struct redisAsyncContext*, int status); 58 | typedef void (redisConnectCallback)(const struct redisAsyncContext*, int status); 59 | 60 | /* Context for an async connection to Redis */ 61 | typedef struct redisAsyncContext { 62 | /* Hold the regular context, so it can be realloc'ed. */ 63 | redisContext c; 64 | 65 | /* Setup error flags so they can be used directly. */ 66 | int err; 67 | char *errstr; 68 | 69 | /* Not used by hiredis */ 70 | void *data; 71 | 72 | /* Event library data and hooks */ 73 | struct { 74 | void *data; 75 | 76 | /* Hooks that are called when the library expects to start 77 | * reading/writing. These functions should be idempotent. */ 78 | void (*addRead)(void *privdata); 79 | void (*delRead)(void *privdata); 80 | void (*addWrite)(void *privdata); 81 | void (*delWrite)(void *privdata); 82 | void (*cleanup)(void *privdata); 83 | } ev; 84 | 85 | /* Called when either the connection is terminated due to an error or per 86 | * user request. The status is set accordingly (REDIS_OK, REDIS_ERR). */ 87 | redisDisconnectCallback *onDisconnect; 88 | 89 | /* Called when the first write event was received. */ 90 | redisConnectCallback *onConnect; 91 | 92 | /* Regular command callbacks */ 93 | redisCallbackList replies; 94 | 95 | /* Subscription callbacks */ 96 | struct { 97 | redisCallbackList invalid; 98 | struct dict *channels; 99 | struct dict *patterns; 100 | } sub; 101 | } redisAsyncContext; 102 | 103 | /* Functions that proxy to hiredis */ 104 | redisAsyncContext *redisAsyncConnect(const char *ip, int port); 105 | redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr); 106 | redisAsyncContext *redisAsyncConnectBindWithReuse(const char *ip, int port, 107 | const char *source_addr); 108 | redisAsyncContext *redisAsyncConnectUnix(const char *path); 109 | int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn); 110 | int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn); 111 | void redisAsyncDisconnect(redisAsyncContext *ac); 112 | void redisAsyncFree(redisAsyncContext *ac); 113 | 114 | /* Handle read/write events */ 115 | void redisAsyncHandleRead(redisAsyncContext *ac); 116 | void redisAsyncHandleWrite(redisAsyncContext *ac); 117 | 118 | /* Command functions for an async context. Write the command to the 119 | * output buffer and register the provided callback. */ 120 | int redisvAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, va_list ap); 121 | int redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *format, ...); 122 | int redisAsyncCommandArgv(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, int argc, const char **argv, const size_t *argvlen); 123 | int redisAsyncFormattedCommand(redisAsyncContext *ac, redisCallbackFn *fn, void *privdata, const char *cmd, size_t len); 124 | 125 | #ifdef __cplusplus 126 | } 127 | #endif 128 | 129 | #endif 130 | -------------------------------------------------------------------------------- /agent/src/c/include/hiredis/read.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2011, Salvatore Sanfilippo 3 | * Copyright (c) 2010-2011, Pieter Noordhuis 4 | * 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | #ifndef __HIREDIS_READ_H 34 | #define __HIREDIS_READ_H 35 | #include /* for size_t */ 36 | 37 | #define REDIS_ERR -1 38 | #define REDIS_OK 0 39 | 40 | /* When an error occurs, the err flag in a context is set to hold the type of 41 | * error that occurred. REDIS_ERR_IO means there was an I/O error and you 42 | * should use the "errno" variable to find out what is wrong. 43 | * For other values, the "errstr" field will hold a description. */ 44 | #define REDIS_ERR_IO 1 /* Error in read or write */ 45 | #define REDIS_ERR_EOF 3 /* End of file */ 46 | #define REDIS_ERR_PROTOCOL 4 /* Protocol error */ 47 | #define REDIS_ERR_OOM 5 /* Out of memory */ 48 | #define REDIS_ERR_OTHER 2 /* Everything else... */ 49 | 50 | #define REDIS_REPLY_STRING 1 51 | #define REDIS_REPLY_ARRAY 2 52 | #define REDIS_REPLY_INTEGER 3 53 | #define REDIS_REPLY_NIL 4 54 | #define REDIS_REPLY_STATUS 5 55 | #define REDIS_REPLY_ERROR 6 56 | 57 | #define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */ 58 | 59 | #ifdef __cplusplus 60 | extern "C" { 61 | #endif 62 | 63 | typedef struct redisReadTask { 64 | int type; 65 | int elements; /* number of elements in multibulk container */ 66 | int idx; /* index in parent (array) object */ 67 | void *obj; /* holds user-generated value for a read task */ 68 | struct redisReadTask *parent; /* parent task */ 69 | void *privdata; /* user-settable arbitrary field */ 70 | } redisReadTask; 71 | 72 | typedef struct redisReplyObjectFunctions { 73 | void *(*createString)(const redisReadTask*, char*, size_t); 74 | void *(*createArray)(const redisReadTask*, int); 75 | void *(*createInteger)(const redisReadTask*, long long); 76 | void *(*createNil)(const redisReadTask*); 77 | void (*freeObject)(void*); 78 | } redisReplyObjectFunctions; 79 | 80 | typedef struct redisReader { 81 | int err; /* Error flags, 0 when there is no error */ 82 | char errstr[128]; /* String representation of error when applicable */ 83 | 84 | char *buf; /* Read buffer */ 85 | size_t pos; /* Buffer cursor */ 86 | size_t len; /* Buffer length */ 87 | size_t maxbuf; /* Max length of unused buffer */ 88 | 89 | redisReadTask rstack[9]; 90 | int ridx; /* Index of current read task */ 91 | void *reply; /* Temporary reply pointer */ 92 | 93 | redisReplyObjectFunctions *fn; 94 | void *privdata; 95 | } redisReader; 96 | 97 | /* Public API for the protocol parser. */ 98 | redisReader *redisReaderCreateWithFunctions(redisReplyObjectFunctions *fn); 99 | void redisReaderFree(redisReader *r); 100 | int redisReaderFeed(redisReader *r, const char *buf, size_t len); 101 | int redisReaderGetReply(redisReader *r, void **reply); 102 | 103 | #define redisReaderSetPrivdata(_r, _p) (int)(((redisReader*)(_r))->privdata = (_p)) 104 | #define redisReaderGetObject(_r) (((redisReader*)(_r))->reply) 105 | #define redisReaderGetError(_r) (((redisReader*)(_r))->errstr) 106 | 107 | #ifdef __cplusplus 108 | } 109 | #endif 110 | 111 | #endif 112 | -------------------------------------------------------------------------------- /agent/src/c/lib/libhiredis.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-php-framework/1e3a5041f3b13983b8a65032c948e323d8d75b65/agent/src/c/lib/libhiredis.a -------------------------------------------------------------------------------- /agent/src/c/lib/libzlog.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-php-framework/1e3a5041f3b13983b8a65032c948e323d8d75b65/agent/src/c/lib/libzlog.a -------------------------------------------------------------------------------- /agent/src/c/release/agent: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-php-framework/1e3a5041f3b13983b8a65032c948e323d8d75b65/agent/src/c/release/agent -------------------------------------------------------------------------------- /agent/src/c/release/agent_log.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | file perms = 644 3 | [formats] 4 | simple = "%d.%ms %m%n" 5 | [rules] 6 | fsof_agent.INFO "../../../../../dubbo-php-framework/agent/log/agent/agent.%d(%F).log", 100M; simple 7 | -------------------------------------------------------------------------------- /agent/src/c/release/agent_server: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-php-framework/1e3a5041f3b13983b8a65032c948e323d8d75b65/agent/src/c/release/agent_server -------------------------------------------------------------------------------- /agent/src/c/release/protect_agent_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd $(dirname $0) 4 | agent_server=$(ps aux | grep 'release/agent_server' | grep -v grep| wc -l) 5 | if [ "$agent_server" -eq "0" ]; then 6 | /bin/bash start_agent_server.sh 7 | fi 8 | -------------------------------------------------------------------------------- /agent/src/c/release/start_agent_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | log_dir="../../../../../dubbo-php-framework/agent/log/agent" 4 | 5 | if [ ! -d $log_dir ]; then 6 | mkdir -p $log_dir 7 | fi 8 | 9 | process=$(ps aux | grep -v "grep" | grep "release/agent_server" | wc -l) 10 | if [ "$process" -ne "0" ]; then 11 | ps aux |grep -v "grep" |grep "release/agent_server"|awk '{print $2}'|xargs kill -9 12 | fi 13 | 14 | cd ../../../../../dubbo-php-framework/agent/src/c/release 15 | cp agent agent_server 16 | chmod u+x agent_server 17 | cur_dir=$(pwd) 18 | $cur_dir/agent_server 600 ../../../../../dubbo-php-framework/config/global/conf/fsof.ini 19 | -------------------------------------------------------------------------------- /agent/src/c/service/fsof_log.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "fsof_log.h" 18 | #include 19 | #include 20 | #include 21 | #include "../common/fsof_util.h" 22 | 23 | 24 | #define LOG_INFO_MAX_LEN (8 * 1024) 25 | #define LOG_DEBUG_INFO_NAME "fsof_agent_log" 26 | 27 | static zlog_category_t *g_zc; 28 | static char g_zlog_conf[MAX_CONFIG_PATH_LEN] = {0}; 29 | 30 | 31 | void fsof_log_info(enum log_level level,const char *format,...) { 32 | char log_info[LOG_INFO_MAX_LEN] = {0}; 33 | va_list v_log; 34 | 35 | va_start(v_log,format); 36 | vsnprintf(log_info,LOG_INFO_MAX_LEN,format,v_log); 37 | va_end(v_log); 38 | 39 | if (g_zc != NULL) { 40 | switch (level) { 41 | case INFO: 42 | zlog_info(g_zc,log_info); 43 | break; 44 | case ERROR: 45 | zlog_error(g_zc,log_info); 46 | break; 47 | case DEBUG: 48 | zlog_debug(g_zc,log_info); 49 | } 50 | } 51 | } 52 | 53 | void fsof_log_close() { 54 | if (g_zc != NULL) { 55 | zlog_fini(); 56 | g_zc = NULL; 57 | } 58 | } 59 | 60 | int fsof_log_init() { 61 | int err = 0; 62 | 63 | get_current_path(g_zlog_conf,"agent_log.conf",1); 64 | err = zlog_init(g_zlog_conf);; 65 | if (err > 0) { 66 | return err; 67 | } 68 | 69 | g_zc = zlog_get_category("fsof_agent"); 70 | if (g_zc == NULL) { 71 | zlog_fini(); 72 | err = 1; 73 | return err; 74 | } 75 | 76 | fsof_log_info(INFO,"log init succeed--------------!!!\n"); 77 | 78 | return 0; // 79 | } 80 | -------------------------------------------------------------------------------- /agent/src/c/service/fsof_log.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef FSOF_LOG_H 18 | #define FSOF_LOG_H 19 | 20 | enum log_level{ 21 | DEBUG = 1, 22 | INFO, 23 | ERROR 24 | }; 25 | int fsof_log_init(); 26 | void fsof_log_info(enum log_level level,const char *format,...); 27 | void fsof_log_close(); 28 | #endif 29 | -------------------------------------------------------------------------------- /agent/src/c/service/fsof_mq.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "fsof_mq.h" 18 | #include 19 | #include 20 | 21 | #define DEFAULT_QUEUE_SIZE (1024) 22 | 23 | struct fsof_queue { 24 | int cap; 25 | int head; 26 | int tail; 27 | int lock; 28 | struct fsof_message *queue; 29 | }; 30 | 31 | struct fsof_queue* fsof_mq_create() { 32 | struct fsof_queue *q = malloc(sizeof(struct fsof_queue)); 33 | if (q == NULL) { 34 | //log info error malloc failed exit 35 | exit(-1); 36 | } 37 | 38 | q->cap = DEFAULT_QUEUE_SIZE; 39 | q->head = 0; 40 | q->tail = 0; 41 | q->lock = 0; 42 | q->queue = malloc(sizeof(struct fsof_message) * q->cap); 43 | if (q->queue == NULL) { 44 | //log info error malloc failed exit 45 | free(q); 46 | exit(-1); 47 | } 48 | 49 | return q; 50 | } 51 | 52 | //expand queue 53 | static void fsof_expand_queue(struct fsof_queue *q) { 54 | struct fsof_message *new_queue = malloc(sizeof(*new_queue) * q->cap * 2); 55 | 56 | int i; 57 | for (i = 0; i < q->cap; i++) { 58 | new_queue[i] = q->queue[i]; 59 | } 60 | 61 | q->head = 0; 62 | q->tail = q->cap; 63 | q->cap *= 2; 64 | free(q->queue); 65 | q->queue = new_queue; 66 | } 67 | 68 | void fsof_mq_push(struct fsof_queue *q,struct fsof_message *message) { 69 | assert(message); 70 | LOCK(q); 71 | 72 | q->queue[q->tail++] = *message; 73 | if (q->tail >= q->cap) { 74 | q->tail = 0; 75 | } 76 | 77 | if (q->head == q->tail) { 78 | fsof_expand_queue(q); 79 | } 80 | 81 | UNLOCK(q); 82 | } 83 | 84 | int fsof_mq_pop(struct fsof_queue *q,struct fsof_message *message) { 85 | int ret = 0; 86 | LOCK(q); 87 | 88 | if (q->head != q->tail) { 89 | *message = q->queue[q->head++]; 90 | ret = 1; 91 | 92 | if (q->head >= q->cap) { 93 | q->head = 0; 94 | } 95 | } 96 | 97 | UNLOCK(q); 98 | return ret; 99 | } 100 | 101 | int fsof_mq_len(struct fsof_queue *q) { 102 | int len = 0; 103 | LOCK(q); 104 | 105 | if (q->head <= q->tail) { 106 | len = q->tail - q->head; 107 | }else { 108 | len = q->tail + q->cap - q->head; 109 | } 110 | 111 | UNLOCK(q); 112 | return len; 113 | } 114 | 115 | int fsof_mq_clear(struct fsof_queue *q) { 116 | LOCK(q); 117 | UNLOCK(q); 118 | int i,j = 0; 119 | for (i = 0; i < q->cap; i++) { 120 | if (q->queue[i].key != NULL) { 121 | free(q->queue[i].key); 122 | } 123 | 124 | for (j = 0; j < q->queue[i].count; j++) { 125 | if (q->queue[i].value[j] != NULL) { 126 | free(q->queue[i].value[j]); 127 | } 128 | } 129 | } 130 | memset(q->queue,0,sizeof(struct fsof_message) * q->cap); 131 | return 0; 132 | } 133 | 134 | void fsof_mq_destroy(struct fsof_queue *q) { 135 | 136 | if(NULL != q) { 137 | if(NULL != q->queue) { 138 | int i,j = 0; 139 | for (i = 0; i < q->cap; i++) { 140 | if (q->queue[i].key != NULL) { 141 | free(q->queue[i].key); 142 | } 143 | 144 | for (j = 0; j < q->queue[i].count; j++) { 145 | if (q->queue[i].value[j] != NULL) { 146 | free(q->queue[i].value[j]); 147 | } 148 | } 149 | } 150 | free(q->queue); 151 | } 152 | 153 | free(q); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /agent/src/c/service/fsof_mq.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef FSOF_MESSAGE_QUEUE_H 18 | #define FSOF_MESSAGE_QUEUE_H 19 | #include 20 | #include 21 | 22 | #define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {} 23 | #define UNLOCK(q) __sync_lock_release(&(q)->lock); 24 | 25 | struct fsof_message { 26 | char *key; 27 | char **value; 28 | int count; //total providers count 29 | }; 30 | 31 | struct fsof_queue; 32 | 33 | //push data into message queue 34 | void fsof_mq_push(struct fsof_queue *q,struct fsof_message *message); 35 | //pop data from message queue 36 | int fsof_mq_pop(struct fsof_queue *q,struct fsof_message *message); 37 | //message queue len 38 | int fsof_mq_len(struct fsof_queue *q); 39 | //message queue struct create 40 | struct fsof_queue* fsof_mq_create(); 41 | //clear message 42 | int fsof_mq_clear(struct fsof_queue *q); 43 | //message queue destroy 44 | void fsof_mq_destroy(struct fsof_queue *q); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /agent/src/c/service/fsof_redis.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef FSOF_REDIS_H 18 | #define FSOF_REDIS_H 19 | 20 | struct fsof_message; 21 | 22 | int fsof_redis_init(const char *path); 23 | int fsof_redis_delete(const char *path); 24 | //compare redis exists provider list with zookeeper exists provider list add by iceli 25 | int compare_and_set_val(const struct fsof_message *message); 26 | //directly set zookeeper exists provider list into redis when redis can't find exists provider list add by iceli 27 | int fsof_redis_setval(const struct fsof_message *message); 28 | struct redisReply* fsof_redis_get(const char *path); 29 | void fsof_redis_close(); 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /agent/src/c/service/fsof_zookeeper.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "fsof_zookeeper.h" 18 | #include "../common/strmap.h" 19 | #include "../common/fsof_global.h" 20 | #include 21 | #include 22 | 23 | #define TIME_OUT 30000 24 | #define ZOOKEEPER_VERSION -1 25 | 26 | extern int errno; 27 | 28 | struct provider_callback { 29 | watcher_fn watcher_cb; 30 | }; 31 | 32 | 33 | static zhandle_t* g_zkhandle = NULL; 34 | static watcher_fn g_watcher_fn; 35 | struct StrMap *g_provider_map; 36 | 37 | 38 | void fsof_zk_create(const char *path,bool ephemeral) { 39 | //nothing to do 40 | } 41 | 42 | int fsof_zk_delete(const char *path) { 43 | int ret; 44 | ret = zoo_delete(g_zkhandle,path,-1); 45 | 46 | return ret; 47 | } 48 | 49 | struct String_vector * fsof_zk_get_children(const char *path) { 50 | int ret = -1; 51 | struct map_object *object_val = NULL; 52 | struct provider_callback *cb = NULL; 53 | struct String_vector *str_list = NULL; 54 | 55 | if (g_zkhandle == NULL) { 56 | return NULL; 57 | } 58 | 59 | str_list = malloc(sizeof(*str_list)); 60 | if (str_list == NULL) { 61 | //log error 62 | exit(-1); 63 | } 64 | 65 | memset(str_list, 0, sizeof(*str_list)); 66 | sm_get(g_provider_map,path,&object_val); 67 | 68 | if (object_val != NULL && object_val->status == 1) { //succeed 69 | if (object_val->type == MAP_OBJECT_CB_TYPE) { 70 | cb = object_val->ptr; 71 | ret = zoo_wget_children(g_zkhandle,path,cb->watcher_cb,NULL,str_list); 72 | } 73 | } else { //0 error,can't get provider callback 74 | ret = zoo_wget_children(g_zkhandle,path,NULL,NULL,str_list); 75 | } 76 | 77 | if (ret < 0) { 78 | //log error 79 | free(str_list); 80 | return NULL; 81 | } 82 | 83 | return str_list; 84 | } 85 | 86 | void fsof_zk_add_listener(const char *path,watcher_fn watcher) { 87 | struct provider_callback *cb = NULL; 88 | struct map_object *object_val = NULL; 89 | 90 | if (sm_exists(g_provider_map,path)) { //exist 91 | sm_get(g_provider_map,path,&object_val); 92 | cb = (struct provider_callback*)object_val->ptr; 93 | if (cb != NULL) { 94 | if (cb->watcher_cb != watcher) { //not same 95 | cb->watcher_cb = watcher; 96 | } 97 | object_val->status = 1; 98 | } 99 | 100 | } else { //create new one 101 | cb = malloc(sizeof(*cb)); 102 | assert(cb); 103 | object_val = malloc(sizeof(*object_val)); 104 | assert(object_val); 105 | cb->watcher_cb = watcher; 106 | object_val->type = MAP_OBJECT_CB_TYPE; 107 | object_val->ptr = cb; 108 | object_val->status = 1; 109 | sm_put(g_provider_map,path,object_val); 110 | } 111 | } 112 | 113 | void fsof_zk_remove_listener(const char *path,watcher_fn watcher) { 114 | struct provider_callback *cb = NULL; 115 | struct map_object *object_val = NULL; 116 | 117 | if (sm_exists(g_provider_map,path)) { //exist 118 | sm_get(g_provider_map,path,&object_val); 119 | if (object_val != NULL) { 120 | cb = (struct provider_callback*)object_val->ptr; 121 | if (cb != NULL && cb->watcher_cb == watcher) { 122 | object_val->status = 0; 123 | } 124 | } 125 | } 126 | } 127 | 128 | void fsof_zk_add_state_listener(watcher_fn watcher) { 129 | g_watcher_fn = watcher; 130 | } 131 | 132 | void fsof_zk_remove_state_listener(watcher_fn watcher) { 133 | g_watcher_fn = NULL; 134 | } 135 | 136 | int fsof_zk_init(const char *host) { 137 | int err = 0; 138 | 139 | if (g_watcher_fn == NULL) { 140 | //log error 141 | exit(-1); 142 | } 143 | 144 | g_zkhandle = zookeeper_init(host,g_watcher_fn,TIME_OUT, 0, "hello zookeeper.", 0); 145 | if (g_zkhandle == NULL) { 146 | //log error 147 | err = errno; //failed 148 | return err; 149 | } 150 | 151 | g_provider_map = sm_new(DEFAULT_MAP_COUNT); 152 | if (g_provider_map == NULL) { 153 | //log error malloc failed 154 | exit(-1); 155 | } 156 | 157 | return err; 158 | } 159 | 160 | void fsof_zk_close() { 161 | if (g_zkhandle != NULL) { 162 | zookeeper_close(g_zkhandle); 163 | 164 | if (g_provider_map != NULL) { 165 | sm_delete(g_provider_map); 166 | g_provider_map = NULL; 167 | } 168 | 169 | g_zkhandle = NULL; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /agent/src/c/service/fsof_zookeeper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef FSOF_ZOOKEEPER_H 18 | #define FSOF_ZOOKEEPER_H 19 | #include "fsof_mq.h" 20 | #include 21 | #include 22 | 23 | 24 | typedef void (*watcher_fn)(zhandle_t* zh, int type, int state, 25 | const char* path, void* watcherCtx); 26 | void fsof_zk_create(const char *path,bool ephemeral); 27 | 28 | int fsof_zk_delete(const char *path); 29 | 30 | struct String_vector * fsof_zk_get_children(const char *path); 31 | 32 | void fsof_zk_add_listener(const char *path,watcher_fn watcher); 33 | 34 | void fsof_zk_remove_listener(const char *path,watcher_fn watcher); 35 | 36 | void fsof_zk_add_state_listener(watcher_fn watcher); 37 | 38 | void fsof_zk_remove_state_listener(watcher_fn watcher); 39 | 40 | int fsof_zk_init(const char *host); 41 | 42 | void fsof_zk_close(); 43 | 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /agent/src/c/service/mt_array.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #include "mt_array.h" 18 | #include "string.h" 19 | 20 | static int mt_array_init(mt_array_t *m,int nalloc,int size); 21 | 22 | mt_array_t *mt_array_create(int nalloc,int size) { 23 | mt_array_t *m = malloc(sizeof(mt_array_t)); 24 | if (m == NULL) { //failed 25 | return NULL; 26 | } 27 | int ret = mt_array_init(m,nalloc,size); 28 | if (ret == -1) { 29 | return NULL; 30 | } 31 | return m; 32 | } 33 | 34 | void *mt_array_push(mt_array_t *m) { 35 | size_t size; 36 | void *new,*elt; 37 | if (m->nalloc == m->nelts) {//full 38 | size = m->size * m->nalloc; 39 | new = malloc(size * 2); 40 | if (new == NULL) { 41 | return NULL; 42 | } 43 | memcpy(new,m->elts,size); 44 | free(m->elts); 45 | m->elts = new; 46 | m->nalloc *= 2; 47 | } 48 | 49 | elt = (char*)m->elts + m->nelts * m->size; 50 | m->nelts++; 51 | return elt; 52 | 53 | } 54 | 55 | void mt_array_destroy(mt_array_t *m) { 56 | if (m->elts != NULL) { 57 | free(m->elts); 58 | free(m); 59 | } 60 | 61 | } 62 | 63 | static int mt_array_init(mt_array_t *m,int nalloc,int size) { 64 | m->nelts = 0; 65 | m->size = size; 66 | m->nalloc = nalloc; 67 | m->elts = malloc(nalloc * size); 68 | if (m->elts == NULL) { 69 | return -1; 70 | } 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /agent/src/c/service/mt_array.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | #ifndef MT_ARRAY_H 18 | #define MT_ARRAY_H 19 | #include 20 | 21 | typedef struct{ 22 | void *elts; 23 | int nelts; 24 | size_t size; 25 | int nalloc; 26 | }mt_array_t; 27 | 28 | mt_array_t *mt_array_create(int nalloc,int size); 29 | void* mt_array_push(mt_array_t *m); 30 | void mt_array_destroy(mt_array_t *m); 31 | #endif 32 | -------------------------------------------------------------------------------- /api/FSOFApi.php: -------------------------------------------------------------------------------- 1 | error("appName or appSrcPath not set,please use FSOFApi::configure() for set."); 51 | return null; 52 | } 53 | else 54 | { 55 | if(!is_numeric($ioTimeout) || $ioTimeout <= 0) 56 | { 57 | $ioTimeout = 3; 58 | } 59 | $consumerFile = dirname(__DIR__).DIRECTORY_SEPARATOR.'consumer'.DIRECTORY_SEPARATOR.'FSOFConsumer.php'; 60 | //加载FSOFConsumer 61 | require_once($consumerFile); 62 | $app_setting = array('app_name' => self::$__FSOF_CONSUMER_APP_NAME__, 'app_src' => self::$__FSOF_CONSUMER_APP_SRC_PATH__); 63 | FSOFConsumer::init($app_setting); 64 | $s = ProxyFactory::getInstance($service, $ioTimeout); 65 | } 66 | return $s; 67 | } 68 | } -------------------------------------------------------------------------------- /arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apache/dubbo-php-framework/1e3a5041f3b13983b8a65032c948e323d8d75b65/arch.png -------------------------------------------------------------------------------- /bin/restartall.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | FSOF_BIN=`pwd`; 4 | DIRECTORY_SEPARATOR="/"; 5 | FILE_NAME="servicename_master_process"; 6 | 7 | #记录启动的服务 8 | ps -ef| grep master_process| grep -v grep > $FSOF_BIN$DIRECTORY_SEPARATOR$FILE_NAME; 9 | 10 | #启动服务进程 11 | while read LINE 12 | do 13 | SER_NAME=`echo $LINE| awk '{print $NF}'|sed 's/_master_process//g'`; 14 | echo "********************Beganing Start" $SER_NAME; 15 | php $FSOF_BIN$DIRECTORY_SEPARATOR"app_admin.php" $SER_NAME restart; 16 | echo "********************Ending Start" $SER_NAME; 17 | done < $FSOF_BIN$DIRECTORY_SEPARATOR$FILE_NAME 18 | -------------------------------------------------------------------------------- /common/BootStrap.php: -------------------------------------------------------------------------------- 1 | $frameRootPathDepth) 37 | { 38 | $key = $className = $class; 39 | if($pathDepth > $frameRootPathDepth + 1) 40 | { 41 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 2); 42 | $className = $root[$frameRootPathDepth + 1]; 43 | unset($root[$frameRootPathDepth + 1]); 44 | $key = implode($root, '\\'); 45 | } 46 | else if($pathDepth == $frameRootPathDepth + 1) 47 | { 48 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 1); 49 | $className = $root[$frameRootPathDepth]; 50 | unset($root[$frameRootPathDepth]); 51 | $key = implode($root, '\\'); 52 | } 53 | 54 | if(isset(self::$nsPath[$key])) 55 | { 56 | include_once self::$nsPath[$key] . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * 设置根命名空间 63 | * @param $root 64 | * @param $path 65 | */ 66 | public static function setRootNS($root, $path) 67 | { 68 | self::$nsPath[$root] = $path; 69 | } 70 | } -------------------------------------------------------------------------------- /common/config/FSOFCommonUtil.php: -------------------------------------------------------------------------------- 1 | $value) 27 | { 28 | $versionWeight = explode(":" ,$value); 29 | if (count($versionWeight) == 1) 30 | { 31 | $versionLists[$value] = 0; 32 | } 33 | else 34 | { 35 | $versionLists[$versionWeight[0]] = $versionWeight[1]; 36 | } 37 | } 38 | return $versionLists; 39 | } 40 | 41 | public static function getWeightSum($versionLists) 42 | { 43 | $weightSum = 0; 44 | foreach ($versionLists as $key => $value) 45 | { 46 | $weightSum += $value; 47 | } 48 | return $weightSum; 49 | } 50 | 51 | public static function getVersionByWeight($versionWeightList) 52 | { 53 | $version = $versionWeightList; 54 | $versionLists = self::parseWeightInfo($versionWeightList); 55 | $weightSum = self::getWeightSum($versionLists); 56 | if ($weightSum > 1) 57 | { 58 | $startValue = 0; 59 | $dstValue = mt_rand(0, $weightSum-1); 60 | foreach ($versionLists as $key => $value) 61 | { 62 | if($dstValue >= $startValue && $dstValue < $value + $startValue) 63 | { 64 | $version = $key; 65 | break; 66 | } 67 | else 68 | { 69 | $startValue += $value; 70 | } 71 | } 72 | } 73 | return $version; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /common/config/FSOFConfigManager.php: -------------------------------------------------------------------------------- 1 | error('fsof.ini is not set environment, default is pro'); 52 | } 53 | return $currentEnv; 54 | } 55 | 56 | public static function getKeepConnect() 57 | { 58 | $keep_connect = false; 59 | $fsof_config_data = self::getFSOFIni(); 60 | if(isset($fsof_config_data['fsof_setting']['keep_connect'])) 61 | { 62 | $keep_connect = $fsof_config_data['fsof_setting']['keep_connect']; 63 | } 64 | return $keep_connect; 65 | } 66 | 67 | public static function isExistProviderDeploy($appName) 68 | { 69 | $deployFile = self::getDeployFile($appName); 70 | if(file_exists($deployFile)) 71 | { 72 | return $deployFile; 73 | } 74 | 75 | \Logger::getLogger(__CLASS__)->error('not deploy '.$appName.":".$deployFile); 76 | return null; 77 | } 78 | 79 | public static function isExistProviderFile($name) 80 | { 81 | $appBootFile = self::getProviderAppRoot($name); 82 | if (isset($appBootFile) && file_exists($appBootFile) && is_file($appBootFile)) 83 | { 84 | return true; 85 | } 86 | else 87 | { 88 | \Logger::getLogger(__CLASS__)->error('not process ' . $name . ":" . $appBootFile); 89 | } 90 | return false; 91 | } 92 | 93 | public static function isProviderAppDeploy($appName) 94 | { 95 | $deployFile = self::getDeployFile($appName); 96 | if(file_exists($deployFile)) 97 | { 98 | $appBootFile = self::getProviderAppRoot($appName); 99 | if(isset($appBootFile) && file_exists($appBootFile) && is_file($appBootFile)) 100 | { 101 | return TRUE; 102 | } 103 | else 104 | { 105 | \Logger::getLogger(__CLASS__)->error("{$appName} bootstrap not exist:".$appBootFile); 106 | } 107 | } 108 | else 109 | { 110 | \Logger::getLogger(__CLASS__)->error("{$appName} deploy file not exist:".$deployFile); 111 | } 112 | return FALSE; 113 | } 114 | 115 | public static function getProviderAppDeploy($appName) 116 | { 117 | $deployFile = self::getDeployFile($appName); 118 | $deployFileData = parse_ini_file($deployFile, TRUE); 119 | return $deployFileData; 120 | } 121 | 122 | public static function getProviderAppRoot($appName) 123 | { 124 | $deployFile = self::getDeployFile($appName); 125 | if(file_exists($deployFile)) 126 | { 127 | $config = parse_ini_file($deployFile, TRUE); 128 | if(isset($config['server']['root'])) 129 | { 130 | $appBootFile = $config['server']['root']; 131 | if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') 132 | { 133 | $appBootFile = str_replace('/', '\\', $appBootFile); 134 | } 135 | if(strpos($appBootFile, DIRECTORY_SEPARATOR) > 0) 136 | { 137 | //对于相对路径,需要拼接成完整路径 138 | $appBootFile = FSOF_PHP_CONFIG_ROOT_PATH.DIRECTORY_SEPARATOR.$appBootFile; 139 | } 140 | return $appBootFile; 141 | } 142 | } 143 | return NULL; 144 | } 145 | 146 | public static function trimall($str) 147 | { 148 | //删除空格,换行符及其它 149 | $qian=array(" "," ","\t","\n","\r"); 150 | $hou=array("","","","",""); 151 | return str_replace($qian,$hou,$str); 152 | } 153 | 154 | public static function isVersion($version) 155 | { 156 | if(empty($version)) 157 | { 158 | return FALSE; 159 | } 160 | $match_times = preg_match('/^(dev\.|prod\.|)\d+\.\d+\.\d+/', $version); 161 | if($match_times > 0) 162 | { 163 | return TRUE; 164 | } 165 | return FALSE; 166 | } 167 | 168 | public static function getDeployVersion($rootPath) 169 | { 170 | $ret = NULL; 171 | $versionFilePath = dirname(dirname($rootPath)).DIRECTORY_SEPARATOR.'version.config'; 172 | if (file_exists($versionFilePath)) 173 | { 174 | $ret = self::trimall(file_get_contents($versionFilePath)); 175 | if(!self::isVersion($ret)) 176 | { 177 | $ret = NULL; 178 | \Logger::getLogger(__CLASS__)->error("version.config: version is error:".$ret); 179 | } 180 | } 181 | return $ret; 182 | } 183 | 184 | public static function selectDeployVersion($bootFile, $version) 185 | { 186 | //插入发布版本信息 187 | if(empty($version) || empty($bootFile)) 188 | { 189 | return $bootFile; 190 | } 191 | $rootPath = explode(DIRECTORY_SEPARATOR, $bootFile); 192 | $num = count($rootPath); 193 | $tmp = array($num+1); 194 | for($i = 0; $i < $num; $i++) 195 | { 196 | if($i < $num-2) 197 | { 198 | $tmp[$i] = $rootPath[$i]; 199 | } 200 | else if($i == $num-2) 201 | { 202 | $tmp[$i] = $version; 203 | $tmp[$i + 1] = $rootPath[$i]; 204 | } 205 | else 206 | { 207 | $tmp[$i + 1] = $rootPath[$i]; 208 | } 209 | } 210 | $bootFile = implode(DIRECTORY_SEPARATOR, $tmp); 211 | return $bootFile; 212 | } 213 | 214 | public static function getProviderAppList() 215 | { 216 | //遍历所有的deploy文件,所有appname采用'*' 217 | $deployDir = self::getDeployFile('*'); 218 | $deploylist = glob($deployDir); 219 | return $deploylist; 220 | } 221 | 222 | public static function getRunProviderList() 223 | { 224 | $pid = FSOF_PROVIDER_PID_PATH.'*.master.pid'; 225 | $pidList = glob($pid); 226 | return $pidList; 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /common/config/FSOFConfigUtil.php: -------------------------------------------------------------------------------- 1 | error($configFile." can not be loaded"); 27 | return array(); 28 | } 29 | $config = parse_ini_file($configFile, true); 30 | return $config; 31 | } 32 | 33 | public static function get($configFile, $key, $default = NULL) 34 | { 35 | $config = self::loadConfigFile($configFile); 36 | $result = isset($config[$key]) ? $config[$key] : $default; 37 | return $result; 38 | } 39 | 40 | public static function getField($configFile, $key, $filed, $default = NULL) 41 | { 42 | $config = self::loadConfigFile($configFile); 43 | $result = isset($config[$key][$filed]) ? $config[$key][$filed] : $default; 44 | return $result; 45 | } 46 | 47 | public static function parse_ini_file_multi($file, $process_sections = false, $scanner_mode = INI_SCANNER_NORMAL) 48 | { 49 | $explode_str = '.'; 50 | $escape_char = "'"; 51 | // load ini file the normal way 52 | $data = parse_ini_file($file, $process_sections, $scanner_mode); 53 | if (!$process_sections) 54 | { 55 | $data = array($data); 56 | } 57 | foreach ($data as $section_key => $section) 58 | { 59 | // loop inside the section 60 | foreach ($section as $key => $value) 61 | { 62 | if (strpos($key, $explode_str)) 63 | { 64 | if (substr($key, 0, 1) !== $escape_char) 65 | { 66 | // key has a dot. Explode on it, then parse each subkeys 67 | // and set value at the right place thanks to references 68 | $sub_keys = explode($explode_str, $key); 69 | $subs =& $data[$section_key]; 70 | foreach ($sub_keys as $sub_key) 71 | { 72 | if (!isset($subs[$sub_key])) 73 | { 74 | $subs[$sub_key] = array(); 75 | } 76 | $subs =& $subs[$sub_key]; 77 | } 78 | // set the value at the right place 79 | $subs = $value; 80 | // unset the dotted key, we don't need it anymore 81 | unset($data[$section_key][$key]); 82 | } 83 | else 84 | { 85 | // we have escaped the key, so we keep dots as they are 86 | $new_key = trim($key, $escape_char); 87 | $data[$section_key][$new_key] = $value; 88 | unset($data[$section_key][$key]); 89 | } 90 | } 91 | } 92 | } 93 | if (!$process_sections) 94 | { 95 | $data = $data[0]; 96 | } 97 | return $data; 98 | } 99 | } -------------------------------------------------------------------------------- /common/config/FSOFConstants.php: -------------------------------------------------------------------------------- 1 | get_redis(); 52 | } 53 | return FSOFRedis::$_instance; 54 | } 55 | else 56 | { 57 | \Logger::getLogger(__CLASS__)->error("not installed redis extension"); 58 | } 59 | return NULL; 60 | } 61 | 62 | public function __construct($config = []) 63 | { 64 | $this->logger = \Logger::getLogger(__CLASS__); 65 | if(isset($config['redis_hosts'])) 66 | { 67 | $this->hosts = []; 68 | $address = explode(',', $config['redis_hosts']); 69 | foreach ($address as $node){ 70 | list($host, $port) = explode(':', $node); 71 | $this->hosts[] = [$host, $port??FSOFConstants::FSOF_SERVICE_REDIS_PORT]; 72 | } 73 | } 74 | if(isset($config['redis_connect_timeout'])) 75 | { 76 | $this->connect_timeout = $config['redis_connect_timeout']; 77 | } 78 | if(isset($config['redis_read_timeout'])) 79 | { 80 | $this->read_timeout = $config['redis_read_timeout']; 81 | } 82 | if(isset($config['redis_connect_type'])) 83 | { 84 | $this->connect_type = $config['redis_connect_type']; 85 | } 86 | if(isset($config['redis_retry_count'])) 87 | { 88 | $this->retry = min($config['redis_retry_count'], 1); 89 | } 90 | } 91 | 92 | public function get_redis() 93 | { 94 | if (!isset($this->m_redis)) 95 | { 96 | $hosts_count = count($this->hosts); 97 | $retry = $this->retry_count; 98 | $rand_num = rand() % $hosts_count; 99 | $ret = false; 100 | do{ 101 | try{ 102 | $redis_cli = new \Redis(); 103 | if($this->connect_type == FSOFConstants::FSOF_SERVICE_REDIS_CONNECT_TYPE_TCP) 104 | { 105 | $node = $this->hosts[$rand_num]; 106 | $ret = $redis_cli->connect($node[0],$node[1],$this->connect_timeout); 107 | $redis_cli->setOption(\Redis::OPT_READ_TIMEOUT, $this->read_timeout); 108 | $rand_num = ($rand_num + 1)%$hosts_count; 109 | if (!$ret) 110 | { 111 | $this->logger->warn("connect redis failed[{$node[0]}:{$node[1]}]"); 112 | } 113 | }else{ 114 | $ret = $redis_cli->connect("/var/fsof/redis.sock",-1,FSOFConstants::FSOF_SERVICE_REDIS_PORT,$this->connect_timeout); 115 | } 116 | if($ret) 117 | { 118 | break; 119 | } 120 | }catch (\Exception $e){ 121 | $this->logger->error('connect redis excepiton:'.$e->getMessage().', errno:' . $e->getCode()); 122 | } 123 | }while($retry-- > 0); 124 | if($ret) 125 | { 126 | $this->m_redis = $redis_cli; 127 | } 128 | else 129 | { 130 | $this->logger->error('connect redis failed:|errno:' . $redis_cli->getLastError()); 131 | throw new \Exception("连接redis异常"); 132 | } 133 | } 134 | 135 | return $this->m_redis; 136 | } 137 | 138 | public function getProviderInfo($key) 139 | { 140 | return $this->getlist($key); 141 | } 142 | 143 | public function get($key) 144 | { 145 | if (!empty($key) && isset($this->m_redis)) 146 | { 147 | return $this->m_redis->get($key); 148 | } 149 | else 150 | { 151 | return NULL; 152 | } 153 | } 154 | 155 | public function getlRange($key) 156 | { 157 | if (!empty($key) && isset($this->m_redis)) 158 | { 159 | return $this->m_redis->lRange($key, 0, -1); 160 | } 161 | else 162 | { 163 | $this->logger->warn('not object of redis:'.$key); 164 | return NULL; 165 | } 166 | } 167 | 168 | public function getlist($key) 169 | { 170 | if (!empty($key) && isset($this->m_redis)) 171 | { 172 | try{ 173 | return $this->getlRange($key); 174 | }catch (\Exception $e){ 175 | $this->logger->warn('redis current connect excepiton'.' |errcode:'.$e->getCode().' |errmsg:'.$e->getMessage()); 176 | $this->close(); 177 | //重试一次防止连接成功后,连接断开 178 | $this->get_redis(); 179 | return $this->getlRange($key); 180 | } 181 | } 182 | else 183 | { 184 | return null; 185 | } 186 | } 187 | 188 | public function set($key, $value) 189 | { 190 | if (!empty($key) && isset($this->m_redis)) 191 | { 192 | return $this->m_redis->set($key, $value); 193 | } 194 | else 195 | { 196 | return null; 197 | } 198 | } 199 | 200 | /** 201 | * Description: 关闭redis连接 202 | */ 203 | public function close() 204 | { 205 | try 206 | { 207 | if (isset($this->m_redis)) 208 | { 209 | $this->m_redis->close(); 210 | unset($this->m_redis); 211 | } 212 | } 213 | catch (\Exception $e) 214 | { 215 | unset($this->m_redis); 216 | $this->logger->error('close redis error:'.$e->getMessage(),$e); 217 | } 218 | } 219 | 220 | public function __destruct() 221 | { 222 | $this->close(); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /common/file/FileSystemUtil.php: -------------------------------------------------------------------------------- 1 | isDot()) 56 | { 57 | continue; 58 | } 59 | 60 | $filename = $file->getFilename(); 61 | 62 | if ($file->isDir()) 63 | { 64 | self::treeDir($dir . DIRECTORY_SEPARATOR . $filename, $filter, $result, $deep); 65 | } 66 | else 67 | { 68 | if(!empty($filter) && !preg_match($filter, $filename)) 69 | { 70 | continue; 71 | } 72 | 73 | if ($deep) 74 | { 75 | $result[$dir][] = $filename; 76 | } 77 | else 78 | { 79 | $result[] = $dir . DIRECTORY_SEPARATOR . $filename; 80 | } 81 | } 82 | } 83 | 84 | return $result; 85 | } 86 | 87 | /** 88 | * 递归删除目录 89 | * @param $dir 90 | * @param $filter 91 | * @return bool 92 | */ 93 | public static function deleteDir($dir, $filter = '') 94 | { 95 | $files = new \DirectoryIterator($dir); 96 | foreach ($files as $file) 97 | { 98 | if ($file->isDot()) 99 | { 100 | continue; 101 | } 102 | 103 | $filename = $file->getFilename(); 104 | 105 | if ($file->isDir()) 106 | { 107 | self::deleteDir($dir . DIRECTORY_SEPARATOR . $filename); 108 | } 109 | else 110 | { 111 | if (!empty($filter) && !preg_match($filter, $filename)) 112 | { 113 | continue; 114 | } 115 | 116 | unlink($dir . DIRECTORY_SEPARATOR . $filename); 117 | } 118 | } 119 | return rmdir($dir); 120 | } 121 | 122 | public static function require_file($path) 123 | { 124 | $bRet = false; 125 | if(is_file($path)) { 126 | require_once($path); 127 | $bRet = true; 128 | } 129 | 130 | return $bRet; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /common/log/FSOFSystemUtil.php: -------------------------------------------------------------------------------- 1 | $local) 34 | { 35 | if ($local != self::$defaultHost) 36 | { 37 | FSOFSystemUtil::$localHost = $local; 38 | break; 39 | } 40 | } 41 | 42 | if (empty(FSOFSystemUtil::$localHost)) 43 | { 44 | FSOFSystemUtil::$localHost = self::$defaultHost; 45 | } 46 | } 47 | else 48 | { 49 | FSOFSystemUtil::$localHost = self::$defaultHost; 50 | } 51 | } 52 | return FSOFSystemUtil::$localHost; 53 | } 54 | 55 | public static function getServiceIP() 56 | { 57 | $result = self::getLocalIP(); 58 | 59 | if ($result == self::$defaultHost) 60 | { 61 | throw new \Exception("本服务器网络地址错误出错"); 62 | } 63 | 64 | return $result; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /common/protocol/fsof/DubboResponse.php: -------------------------------------------------------------------------------- 1 | fullData; 45 | } 46 | 47 | /** 48 | * @param mixed $fullData 49 | */ 50 | public function setFullData($fullData) 51 | { 52 | $this->fullData = $fullData; 53 | } 54 | 55 | /** 56 | * @return int 57 | */ 58 | public function getStatus() 59 | { 60 | return $this->status; 61 | } 62 | 63 | /** 64 | * @return mixed 65 | */ 66 | public function getLen() 67 | { 68 | return $this->len; 69 | } 70 | 71 | /** 72 | * @param mixed $len 73 | */ 74 | public function setLen($len) 75 | { 76 | $this->len = $len; 77 | } 78 | 79 | /** 80 | * @param int $status 81 | */ 82 | public function setStatus($status) 83 | { 84 | $this->status = $status; 85 | } 86 | 87 | /** 88 | * @return boolean 89 | */ 90 | public function isHeartbeatEvent() 91 | { 92 | return $this->heartbeatEvent; 93 | } 94 | 95 | /** 96 | * @param boolean $heartbeatEvent 97 | */ 98 | public function setHeartbeatEvent($heartbeatEvent) 99 | { 100 | $this->heartbeatEvent = $heartbeatEvent; 101 | } 102 | 103 | 104 | 105 | 106 | /** 107 | * @return mixed 108 | */ 109 | public function getErrorMsg() 110 | { 111 | return $this->errorMsg; 112 | } 113 | 114 | /** 115 | * @param mixed $errorMsg 116 | */ 117 | public function setErrorMsg($errorMsg) 118 | { 119 | $this->errorMsg = $errorMsg; 120 | } 121 | 122 | /** 123 | * @return mixed 124 | */ 125 | public function getSn() 126 | { 127 | return $this->sn; 128 | } 129 | 130 | /** 131 | * @param mixed $sn 132 | */ 133 | public function setSn($sn) 134 | { 135 | $this->sn = $sn; 136 | } 137 | 138 | /** 139 | * @return mixed 140 | */ 141 | public function getResult() 142 | { 143 | return $this->result; 144 | } 145 | 146 | /** 147 | * @param mixed $result 148 | */ 149 | public function setResult($result) 150 | { 151 | $this->result = $result; 152 | } 153 | 154 | /** 155 | * @return mixed 156 | */ 157 | public function getSerialization() 158 | { 159 | return $this->serialization; 160 | } 161 | 162 | /** 163 | * @param mixed $serialization 164 | */ 165 | public function setSerialization($serialization) 166 | { 167 | $this->serialization = $serialization; 168 | } 169 | 170 | /** 171 | * @return mixed 172 | */ 173 | public function getResponseBody() 174 | { 175 | return $this->responseBody; 176 | } 177 | 178 | /** 179 | * @param mixed $responseBody 180 | */ 181 | public function setResponseBody($responseBody) 182 | { 183 | $this->responseBody = $responseBody; 184 | } 185 | 186 | 187 | 188 | public function __toString() 189 | { 190 | $ret = sprintf("%s->%s", $this->sn,$this->responseBody); 191 | return $ret; 192 | } 193 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "apache/log4php": "^2.3", 4 | "crazyxman/hessian-parser": "dev-master" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /config/app/conf/dev/provider/demo-provider.deploy: -------------------------------------------------------------------------------- 1 | [server] 2 | ; port 3 | listen[] = 10000 4 | 5 | ;app log config file path 6 | log_cfg_file_path = '/root/fsof_php_core/dubbo-php-framework/demo/demo-provider/config/log4php.xml' 7 | 8 | ;swoole log path 9 | swoole_log_path = '/var/fsof/provider/example_swoole.log' 10 | 11 | ; point to app root path's bootstrap.php 12 | root = '/root/fsof_php_core/dubbo-php-framework/demo/demo-provider/BootStrap.php' 13 | 14 | [setting] 15 | ; worker num 16 | worker_num = 2 17 | 18 | ; daemonize 19 | daemonize = true 20 | 21 | ;max_request 22 | max_request = 1 23 | -------------------------------------------------------------------------------- /config/app/conf/gray/provider/example.deploy: -------------------------------------------------------------------------------- 1 | [server] 2 | ; port 3 | listen[] = 10000 4 | 5 | ;Provider app log level INFO WARN ERROR 6 | log_level = INFO 7 | 8 | ;base service log level INFO WARN ERROR 9 | bslog_level = INFO 10 | 11 | ; point to app root path's bootstrap.php 12 | root = '../example/provider/src/BootStrap.php' 13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 14 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 15 | [setting] 16 | ; worker num 17 | worker_num = 2 18 | 19 | ; daemonize 20 | daemonize = true -------------------------------------------------------------------------------- /config/app/conf/pre/provider/example.deploy: -------------------------------------------------------------------------------- 1 | [server] 2 | ; port 3 | listen[] = 10000 4 | 5 | ;Provider app log level INFO WARN ERROR 6 | log_level = INFO 7 | 8 | ;base service log level INFO WARN ERROR 9 | bslog_level = INFO 10 | 11 | ; point to app root path's bootstrap.php 12 | root = '../example/provider/src/BootStrap.php' 13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 14 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 15 | [setting] 16 | ; worker num 17 | worker_num = 2 18 | 19 | ; daemonize 20 | daemonize = true 21 | 22 | 23 | -------------------------------------------------------------------------------- /config/app/conf/pro/provider/example.deploy: -------------------------------------------------------------------------------- 1 | [server] 2 | ; port 3 | listen[] = 10000 4 | 5 | ;Provider app log level INFO WARN ERROR 6 | log_level = INFO 7 | 8 | ;base service log level INFO WARN ERROR 9 | bslog_level = INFO 10 | 11 | ; point to app root path's bootstrap.php 12 | root = '../example/provider/src/BootStrap.php' 13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 14 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 15 | [setting] 16 | ; worker num 17 | worker_num = 2 18 | 19 | ; daemonize 20 | daemonize = true -------------------------------------------------------------------------------- /config/global/conf/fsof.ini: -------------------------------------------------------------------------------- 1 | [fsof_container_setting] 2 | ;php path 3 | php = '/usr/bin/php' 4 | 5 | ;app's user 6 | user = root 7 | 8 | [fsof_setting] 9 | ;machine enviroment:[dev|pre|gray|pro] 10 | environment = dev 11 | 12 | ;in p2p mode, provider not register to registry 13 | p2p_mode = false 14 | 15 | ;zookeeper log switch: 0.close; 1.error; 2.warn; 3.info; 4.debug 16 | zklog_level = 0 17 | 18 | ;zookeepr log path 19 | zklog_path = '/var/fsof/provider/zookeeper.log' 20 | 21 | ;zookeeper url list 22 | zk_url_list = http://127.0.0.1:2181 23 | 24 | ;provider overload mode switch 25 | overload_mode = true 26 | 27 | ;if request wait more than waiting_time before processed, we will lost this quest, unit is micro-second 28 | waiting_time = 2000 29 | 30 | ;if overload_number requests trigger overload rule continuous, we will open loss request mode 31 | overload_number = 5 32 | 33 | ;how many quest is lost before lost mode is close 34 | loss_number = 20 -------------------------------------------------------------------------------- /consumer/ConsumerException.php: -------------------------------------------------------------------------------- 1 | info("consumer cfg:".json_encode($settings, true)); 40 | 41 | $consumerRoot = __DIR__; 42 | $fsofBootPath = dirname($consumerRoot); 43 | 44 | //加载commom 45 | $fsofCommonPath = $fsofBootPath.DIRECTORY_SEPARATOR.'common'; 46 | require_once($fsofCommonPath.DIRECTORY_SEPARATOR.'BootStrap.php'); 47 | 48 | //加载registry 49 | $fsofRegistryPath = $fsofBootPath.DIRECTORY_SEPARATOR.'registry'; 50 | require_once($fsofRegistryPath.DIRECTORY_SEPARATOR.'BootStrap.php'); 51 | 52 | //检查输入参数app_src 53 | if ((!isset($settings['app_src'])) || (!isset($settings['app_name']))) 54 | { 55 | throw new \Exception("FSOFConsumer::init传入的app的src路径参数不准确"); 56 | } 57 | $consumerConfigFile = $settings['app_src']; 58 | $consumerConfigFile = rtrim($consumerConfigFile, DIRECTORY_SEPARATOR); 59 | $consumerConfigFile = $consumerConfigFile.DIRECTORY_SEPARATOR.'consumer'.DIRECTORY_SEPARATOR.$settings['app_name'].'.consumer'; 60 | if (file_exists($consumerConfigFile)) 61 | { 62 | try 63 | { 64 | $consumerConfig = parse_ini_file($consumerConfigFile, true); 65 | } 66 | catch (\Exception $e) 67 | { 68 | throw new \Exception("consumer配置文件有误[".$consumerConfigFile."]"); 69 | } 70 | } 71 | else 72 | { 73 | $consumerConfig = array(); 74 | } 75 | 76 | self::$_initSetting = $settings; 77 | 78 | //注册consumer框架的autoLoader 79 | self::registerConsumerFrameAutoLoader($consumerRoot); 80 | 81 | //注册consumer的动态代理工厂 82 | ProxyFactory::setConsumerConfig($consumerConfig, $consumerConfigFile, $settings); 83 | 84 | // FSOFConsumer is now initialized 85 | self::$_init = TRUE; 86 | } 87 | 88 | private static function registerConsumerFrameAutoLoader($consumerRoot) 89 | { 90 | if (!self::isConsumerInit()) 91 | { 92 | //注册框架顶层命名空间到自动加载器 93 | require_once $consumerRoot.DIRECTORY_SEPARATOR.'FrameAutoLoader.php'; 94 | FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer', $consumerRoot); 95 | FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\app', $consumerRoot.DIRECTORY_SEPARATOR.'app'); 96 | FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\fsof', $consumerRoot.DIRECTORY_SEPARATOR.'fsof'); 97 | FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\proxy', $consumerRoot.DIRECTORY_SEPARATOR.'proxy'); 98 | FrameAutoLoader::setRootNS('com\fenqile\fsof\consumer\client', $consumerRoot.DIRECTORY_SEPARATOR.'client'); 99 | spl_autoload_register(__NAMESPACE__.'\FrameAutoLoader::autoload'); 100 | } 101 | } 102 | 103 | public static function getInitSetting() 104 | { 105 | return self::$_initSetting; 106 | } 107 | 108 | public static function isConsumerInit() 109 | { 110 | return self::$_init; 111 | } 112 | 113 | } -------------------------------------------------------------------------------- /consumer/FrameAutoLoader.php: -------------------------------------------------------------------------------- 1 | $frameRootPathDepth) 37 | { 38 | $key = $className = $class; 39 | if($pathDepth > $frameRootPathDepth + 1) 40 | { 41 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 2); 42 | $className = $root[$frameRootPathDepth + 1]; 43 | unset($root[$frameRootPathDepth + 1]); 44 | $key = implode($root, '\\'); 45 | } 46 | else if($pathDepth == $frameRootPathDepth + 1) 47 | { 48 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 1); 49 | $className = $root[$frameRootPathDepth]; 50 | unset($root[$frameRootPathDepth]); 51 | $key = implode($root, '\\'); 52 | } 53 | 54 | if(isset(self::$nsPath[$key])) 55 | { 56 | include_once self::$nsPath[$key] . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * 设置根命名空间 63 | * @param $root 64 | * @param $path 65 | */ 66 | public static function setRootNS($root, $path) 67 | { 68 | self::$nsPath[$root] = $path; 69 | } 70 | } -------------------------------------------------------------------------------- /consumer/Type.php: -------------------------------------------------------------------------------- 1 | 'S', 28 | Type::INT => 'I', 29 | Type::LONG => 'J', 30 | Type::FLOAT => 'F', 31 | Type::DOUBLE => 'D', 32 | Type::BOOLEAN => 'Z', 33 | Type::STRING => 'Ljava/lang/String;', 34 | Type::MAP => 'Ljava/util/Map;', 35 | */ 36 | Type::ARRAYLIST => 'Ljava/util/ArrayList;', 37 | Type::DEFAULT_TYPE => 'Ljava/lang/Object;' 38 | ]; 39 | 40 | private function __construct() 41 | { 42 | } 43 | 44 | /** 45 | * 46 | * @param integer $value 47 | * @return UniversalObject 48 | */ 49 | public static function object($class, $properties) 50 | { 51 | $typeObj = new self(); 52 | $typeObj->className = $class; 53 | $std = new \stdClass; 54 | foreach ($properties as $key => $value) { 55 | $std->$key = $value; 56 | } 57 | $typeObj->object = $std; 58 | return $typeObj; 59 | } 60 | 61 | /** 62 | * 63 | * @param mixed $arg 64 | * @return string 65 | * @throws ConsumerException 66 | */ 67 | public static function argToType($arg) 68 | { 69 | $type = gettype($arg); 70 | switch ($type) { 71 | case 'integer': 72 | case 'boolean': 73 | case 'double': 74 | case 'string': 75 | case 'NULL': 76 | return self::adapter[Type::DEFAULT_TYPE]; 77 | case 'array': 78 | if (Collection::isSequential($arg)) { 79 | return self::adapter[Type::ARRAYLIST]; 80 | } else { 81 | return self::adapter[Type::DEFAULT_TYPE]; 82 | } 83 | case 'object': 84 | if ($arg instanceof Type) { 85 | $className = $arg->className; 86 | } else { 87 | $className = get_class($arg); 88 | } 89 | return 'L' . str_replace(['.', '\\'], '/', $className) . ';'; 90 | default: 91 | throw new ConsumerException("Handler for type {$type} not implemented"); 92 | } 93 | } 94 | /** 95 | * 96 | * @param int $arg 97 | * @return int 98 | */ 99 | 100 | /* 101 | private static function numToType($value) 102 | { 103 | if (-32768 <= $value && $value <= 32767) { 104 | return Type::SHORT; 105 | } elseif (-2147483648 <= $value && $value <= 2147483647) { 106 | return Type::INT; 107 | } 108 | return Type::LONG; 109 | } 110 | */ 111 | 112 | } -------------------------------------------------------------------------------- /consumer/client/FSOFClient4Linux.php: -------------------------------------------------------------------------------- 1 | logger = \Logger::getLogger(__CLASS__); 26 | if (extension_loaded('swoole')) 27 | { 28 | try 29 | { 30 | $this->client = new \swoole_client(SWOOLE_SOCK_TCP); 31 | $this->client->set(array( 32 | 'open_length_check' => TRUE, 33 | 'package_length_offset' => 12, //第N个字节是包长度的值 34 | 'package_body_offset' => 16, //第几个字节开始计算长度 35 | 'package_length_type' => 'N', 36 | 'package_max_length' => 1024 * 1024 * 5, //TCP协议最大长度为2M,暂定5M 37 | )); 38 | } 39 | catch (\Exception $e) 40 | { 41 | $this->logger->error("not installed swoole extension", $e); 42 | throw new \Exception("该环境未安装swoole扩展"); 43 | } 44 | } 45 | else 46 | { 47 | $this->logger->error("not installed swoole extension"); 48 | throw new \Exception("该环境未安装swoole扩展"); 49 | } 50 | } 51 | 52 | public function connect($ipAddr, $port, $ioTimeOut) 53 | { 54 | try 55 | { 56 | return $this->client->connect($ipAddr, $port, $ioTimeOut); 57 | } 58 | catch (\Exception $e) 59 | { 60 | $this->logger->error("connect FSOF server[".$ipAddr.":".$port ."] failed", $e); 61 | return false; 62 | } 63 | } 64 | 65 | public function send($data, $len) 66 | { 67 | return $this->client->send($data); 68 | } 69 | 70 | public function recv($len = 65535) 71 | { 72 | return $this->client->recv($len, true); 73 | } 74 | 75 | public function close($force = false) 76 | { 77 | try 78 | { 79 | $this->client->close($force); 80 | } 81 | catch (\Exception $e) 82 | { 83 | $this->logger->error("close exception", $e); 84 | } 85 | } 86 | 87 | public function getlasterror() 88 | { 89 | return $this->client->errCode; 90 | } 91 | } -------------------------------------------------------------------------------- /consumer/client/IFSOFClient.php: -------------------------------------------------------------------------------- 1 | logger = \Logger::getLogger(__CLASS__); 50 | $this->serviceInterface = $serviceInterfaces; 51 | $this->appName = $appName; 52 | $this->group = $group; 53 | $this->fsofProcessor = new FSOFProcessor(); 54 | } 55 | 56 | public function setIOTimeOut($ioTimeOut) 57 | { 58 | $this->ioTimeOut = $ioTimeOut; 59 | } 60 | 61 | public function setAddress($serviceAddr = array()) 62 | { 63 | //删除旧的地址 64 | unset($this->serviceAddress); 65 | $this->serviceAddress = $serviceAddr; 66 | } 67 | 68 | public function getAddressStr() 69 | { 70 | $ret = ""; 71 | foreach ($this->serviceAddress as $index => $url) 72 | { 73 | $ret .= $url->getHost().':'.$url->getPort().';'; 74 | } 75 | return $ret; 76 | } 77 | 78 | protected function generatePackageSN() 79 | { 80 | srand((double)microtime() * 1000000); 81 | $rand_number = rand(); 82 | return $rand_number; 83 | } 84 | 85 | protected function generateParamType($args) 86 | { 87 | $types = []; 88 | foreach ($args as $val) { 89 | $types[] = Type::argToType($val); 90 | } 91 | return $types; 92 | } 93 | 94 | protected function trimParams($params) 95 | { 96 | if(count($params) == 1 && empty($params[0])) 97 | { 98 | return null; 99 | } 100 | return $params; 101 | } 102 | 103 | public function __call($name, $args) 104 | { 105 | $result = NULL; 106 | $method = null; 107 | $providerAddress = NULL; 108 | $request = new DubboRequest(); 109 | //取到微秒 110 | $begin_time = microtime(true); 111 | $this->logger->debug("in|consumer_app:{$this->appName}|service:{$this->serviceInterface}|timout:{$this->ioTimeOut}|name:{$name}"); 112 | try { 113 | $request->setSn($this->generatePackageSN()); 114 | $request->setService($this->serviceInterface); 115 | $request->setMethod($args[0]); 116 | array_shift($args); 117 | $request->setTypes($this->generateParamType($args)); 118 | $request->setParams($args); 119 | $result = $this->fsofProcessor->executeRequest($request, $this->serviceAddress, $this->ioTimeOut, $providerAddress); 120 | }catch (\Exception $e) { 121 | $cost_time = (int)((microtime(true) - $begin_time) * 1000000); 122 | //记录consumer接口告警日志 123 | $this->setAccLog($request, $cost_time, $e->getMessage()); 124 | throw new ConsumerException($e->getMessage(), $e); 125 | } 126 | $cost_time = (int)((microtime(true) - $begin_time) * 1000000); 127 | //记录consumer接口告警日志 128 | $this->setAccLog($request, $cost_time, "ok"); 129 | return $result; 130 | } 131 | 132 | protected function setAccLog($request, $costTime, $errMsg='ok') 133 | { 134 | //时间|服务名|耗时(us)|返回码|应用名|方法名|目标服务group|目标服务version|目标机器ip:port|备注 135 | $accLog = sprintf("%s|%d|%d|%s|%s|%s|%s|%s", $request->getService(), $costTime, 136 | $this->appName, 137 | $request->getMethod(), 138 | $request->getGroup(), 139 | $request->getVersion(), 140 | $request->host . ':' . $request->port, 141 | $errMsg); 142 | $this->logger->debug($accLog); 143 | } 144 | } -------------------------------------------------------------------------------- /consumer/proxy/ProxyFactory.php: -------------------------------------------------------------------------------- 1 | getProviders($service, $version, $group); 114 | if(!empty($providerInfo)) 115 | { 116 | $cacheKey = $service.':'.$version.':'.$group; 117 | if(empty(self::$serviceInstances[$cacheKey])) 118 | { 119 | $ret = Proxy::newProxyInstance($service, self::$appName, $group); 120 | self::$serviceInstances[$cacheKey] = $ret; 121 | } 122 | else 123 | { 124 | $ret = self::$serviceInstances[$cacheKey]; 125 | } 126 | 127 | //设置io超时时间 128 | $ret->setIOTimeOut($ioTimeOut); 129 | 130 | //设置地址列表 131 | $ret->setAddress($providerInfo); 132 | } 133 | else 134 | { 135 | self::$logger->error("not find providers form redis for $service:$version:$group"); 136 | } 137 | 138 | return $ret; 139 | } 140 | 141 | //use p2p mode 142 | private static function getInstanceByP2P($service, $ioTimeOut, $version, $group) 143 | { 144 | $ret = NULL; 145 | if(array_key_exists($service, self::$serviceConsumers)) 146 | { 147 | $serviceProperty = self::$serviceConsumers[$service]; 148 | if (isset($serviceProperty['url'])) 149 | { 150 | $ret = Proxy::newProxyInstance($service, self::$appName, $group); 151 | 152 | //设置io超时时间 153 | $ret->setIOTimeOut($ioTimeOut); 154 | 155 | //设置所用服务的ip地址列表 156 | $serviceAddr = explode(",",$serviceProperty['url']); 157 | $serviceUrls = array(); 158 | foreach ($serviceAddr as $index => $addr) 159 | { 160 | $tmpUrl = $addr.'/'."{$service}?version={$version}&group={$group}"; 161 | $serviceUrls[] = new FSOFUrl($tmpUrl); 162 | } 163 | $ret->setAddress($serviceUrls); 164 | } 165 | else 166 | { 167 | self::$logger->warn(self::$appName.'.consumer not exist url'); 168 | } 169 | } 170 | else 171 | { 172 | self::$logger->warn('service not found on p2p|consumer_app:'.self::$appName.'|provider_service:'.$service); 173 | } 174 | 175 | return $ret; 176 | } 177 | 178 | public static function getInstance($consumerInterface, $ioTimeOut = 3, $version = null, $group = null) 179 | { 180 | $ret = NULL; 181 | $route = ''; 182 | $addressList = 'null'; 183 | 184 | //app级组和版本信息 185 | $group = self::$appGroup; 186 | $versionList = self::$appVersion; 187 | 188 | if (array_key_exists($consumerInterface, self::$serviceConsumers)) 189 | { 190 | $serviceProperty = self::$serviceConsumers[$consumerInterface]; 191 | if(isset($serviceProperty['group'])) 192 | { 193 | $group = $serviceProperty['group']; 194 | } 195 | if(isset($serviceProperty['version'])) 196 | { 197 | $versionList = $serviceProperty['version']; 198 | } 199 | } 200 | 201 | try 202 | { 203 | 204 | //依据配置权重选取版本号 205 | $version = FSOFCommonUtil::getVersionByWeight($versionList); 206 | 207 | //p2p模式 208 | if (self::$p2pMode) 209 | { 210 | $ret = self::getInstanceByP2P($consumerInterface, $ioTimeOut, $version, $group); 211 | $route = 'p2p'; 212 | } 213 | 214 | if (empty($ret)) 215 | { 216 | //registry 模式 217 | $ret = self::getInstancByRedis($consumerInterface, $ioTimeOut, $version, $group); 218 | $route = 'auto registry'; 219 | } 220 | 221 | if (empty($ret)) 222 | { 223 | $errMsg = "current_address:".FSOFSystemUtil::getLocalIP()."|".$consumerInterface; 224 | throw new ConsumerException($errMsg); 225 | } 226 | else 227 | { 228 | $addressList = $ret->getAddressStr(); 229 | } 230 | self::$logger->debug('consumer_app:'.self::$appName.'|app_config_file:'.self::$appConfigFile. 231 | '|version:'.$version.'|group:'.$group.'|provider_service:'.$consumerInterface.'|route:'.$route.'|addr_list:'.$addressList.'|timeout:'.$ioTimeOut); 232 | } 233 | catch (\Exception $e) 234 | { 235 | self::$logger->error('consumer_app:'.self::$appName.'|app_config_file:'.self::$appConfigFile. 236 | '|version:'.$version.'|group:'.$group.'|provider_service:'.$consumerInterface.'|errmsg:'. $e->getMessage().'|exceptionmsg:'.$e); 237 | throw new ConsumerException($e->getMessage(), $e); 238 | } 239 | return $ret; 240 | } 241 | } -------------------------------------------------------------------------------- /demo/demo-consumer/config/log4php.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /demo/demo-consumer/consumer/demo-consumer.consumer: -------------------------------------------------------------------------------- 1 | [consumer_config] 2 | p2p_mode = false 3 | 4 | [consumer_services] 5 | 6 | com.fenqile.example.DemoService[group] = * 7 | com.fenqile.example.DemoService[version] = 1.0.0 8 | 9 | com.fenqile.arch.dubbo.service.DemoPhpService[group] = * 10 | com.fenqile.arch.dubbo.service.DemoPhpService[version] = 1.0.0 -------------------------------------------------------------------------------- /demo/demo-consumer/server/Consumer.php: -------------------------------------------------------------------------------- 1 | invoke("sayHello","zhangsan"); 15 | echo "ret:$ret".PHP_EOL; 16 | -------------------------------------------------------------------------------- /demo/demo-provider/BootStrap.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /demo/demo-provider/provider/demo-provider.provider: -------------------------------------------------------------------------------- 1 | [service_properties] 2 | owner = author 3 | version = 1.0.0 4 | group = default 5 | 6 | [service_providers] 7 | com.fenqile.example.DemoService[service] = DemoServiceImpl 8 | com.fenqile.example.DemoService[version] = 1.0.0 9 | com.fenqile.example.DemoService[group] = default -------------------------------------------------------------------------------- /demo/demo-provider/server/DemoServiceImpl.php: -------------------------------------------------------------------------------- 1 | info("Hello $name"); 16 | return "Hello $name"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /provider/FSOFProvider.php: -------------------------------------------------------------------------------- 1 | 'Exception', 46 | 'message' => $exception->getMessage(), 47 | 'code' => $exception->getCode(), 48 | 'file' => $exception->getFile(), 49 | 'line' => $exception->getLine(), 50 | 'trace' => array(), 51 | ); 52 | 53 | $traceItems = $exception->getTrace(); 54 | foreach ($traceItems as $traceItem) 55 | { 56 | $traceHash = array( 57 | 'file' => isset($traceItem['file']) ? $traceItem['file'] : 'null', 58 | 'line' => isset($traceItem['line']) ? $traceItem['line'] : 'null', 59 | 'function' => isset($traceItem['function']) ? $traceItem['function'] : 'null', 60 | 'args' => array(), 61 | ); 62 | 63 | if (!empty($traceItem['class'])) 64 | { 65 | $traceHash['class'] = $traceItem['class']; 66 | } 67 | 68 | if (!empty($traceItem['type'])) 69 | { 70 | $traceHash['type'] = $traceItem['type']; 71 | } 72 | 73 | if (!empty($traceItem['args'])) 74 | { 75 | foreach ($traceItem['args'] as $argsItem) 76 | { 77 | $traceHash['args'][] = \var_export($argsItem, true); 78 | } 79 | } 80 | 81 | $exceptionHash['trace'][] = $traceHash; 82 | } 83 | 84 | \Logger::getLogger(__CLASS__)->error(print_r($exceptionHash, true)); 85 | } 86 | set_exception_handler(__NAMESPACE__ . '\exceptionHandler'); -------------------------------------------------------------------------------- /provider/FrameAutoLoader.php: -------------------------------------------------------------------------------- 1 | $frameRootPathDepth) 37 | { 38 | $key = $className = $class; 39 | if($pathDepth > $frameRootPathDepth + 1) 40 | { 41 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 2); 42 | $className = $root[$frameRootPathDepth + 1]; 43 | unset($root[$frameRootPathDepth + 1]); 44 | $key = implode($root, '\\'); 45 | } 46 | else if($pathDepth == $frameRootPathDepth + 1) 47 | { 48 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 1); 49 | $className = $root[$frameRootPathDepth]; 50 | unset($root[$frameRootPathDepth]); 51 | $key = implode($root, '\\'); 52 | } 53 | 54 | if(isset(self::$nsPath[$key])) 55 | { 56 | include_once self::$nsPath[$key] . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * 设置根命名空间 63 | * @param $root 64 | * @param $path 65 | */ 66 | public static function setRootNS($root, $path) 67 | { 68 | self::$nsPath[$root] = $path; 69 | } 70 | } -------------------------------------------------------------------------------- /provider/common/Console.php: -------------------------------------------------------------------------------- 1 | $path) 63 | { 64 | $class_file = $path.DIRECTORY_SEPARATOR.$newClassName.".php"; 65 | if (is_file($class_file)) 66 | { 67 | require_once($class_file); 68 | break; 69 | } 70 | } 71 | } 72 | 73 | /** 74 | * [setRoot 设置root根目录,可以同时添加多个] 75 | * @param array $root [array] 76 | */ 77 | public static function setRoot($rootArr = array()) 78 | { 79 | if(is_array($rootArr)) 80 | { 81 | self::$root_path = array_merge(self::$root_path, $rootArr); 82 | 83 | foreach (self::$root_path as $key => $value) 84 | { 85 | self::$class_autoload_path = array_merge(self::$class_autoload_path,self::set_include_path($value)); 86 | } 87 | } 88 | } 89 | 90 | /** 91 | * [addRoot 添加root节点,可以多节点实现auto_load] 92 | * @param [type] $root [description] 93 | */ 94 | public static function addRoot($root) 95 | { 96 | \Logger::getLogger(__CLASS__)->debug('addRoot() in '.$root); 97 | if(isset($root)) 98 | { 99 | self::$root_path[] = $root; 100 | foreach (self::$root_path as $key => $value) 101 | { 102 | self::$class_autoload_path = array_merge(self::$class_autoload_path,self::set_include_path($value)); 103 | } 104 | } 105 | \Logger::getLogger(__CLASS__)->debug('addRoot() out '.print_r(self::$class_autoload_path, true)); 106 | } 107 | 108 | /** 109 | * [getFatherPath 获取父级目录路径] 110 | * @param [type] $path [description] 111 | * @param integer $num [父级的级数,默认是当前目录的上一级目录] 112 | * @return [type] [路径字符串] 113 | */ 114 | public static function getFatherPath($path, $num = 1) 115 | { 116 | if (empty($path)) 117 | { 118 | return ""; 119 | } 120 | 121 | for ($i = 0; $i < $num; $i++) 122 | { 123 | $path = substr($path,0,strrpos($path ,DIRECTORY_SEPARATOR)); 124 | } 125 | return $path; 126 | } 127 | } 128 | 129 | spl_autoload_register(array(__NAMESPACE__ . '\AppAutoLoader','auto_load')); -------------------------------------------------------------------------------- /provider/core/app/AppContext.php: -------------------------------------------------------------------------------- 1 | stateless = $stateless; 32 | $this->server = $server; 33 | } 34 | 35 | public function isStateless() 36 | { 37 | return $this->stateless; 38 | } 39 | 40 | public function getInstance($className, $params = null) 41 | { 42 | if($this->stateless) 43 | { 44 | \Logger::getLogger(__CLASS__)->debug("get stateless instance for $className"); 45 | if (isset($this->instances[$className])) 46 | { 47 | return $this->instances[$className]; 48 | } 49 | 50 | if (!class_exists($className,true)) 51 | { 52 | throw new \Exception("no class {$className}"); 53 | } 54 | 55 | if (empty($params)) 56 | { 57 | $this->instances[$className] = new $className(); 58 | } 59 | else 60 | { 61 | $this->instances[$className] = new $className($params); 62 | } 63 | 64 | return $this->instances[$className]; 65 | } 66 | else 67 | { 68 | \Logger::getLogger(__CLASS__)->debug("get new instance for $className"); 69 | if (!class_exists($className,true)) 70 | { 71 | throw new \Exception("no class {$className}"); 72 | } 73 | 74 | if (empty($params)) 75 | { 76 | return new $className(); 77 | } 78 | else 79 | { 80 | return new $className($params); 81 | } 82 | } 83 | } 84 | } -------------------------------------------------------------------------------- /provider/core/app/AppLauncher.php: -------------------------------------------------------------------------------- 1 | init(); 30 | } 31 | 32 | abstract public function init(); 33 | 34 | public function setServer($server) 35 | { 36 | $this->server = $server; 37 | } 38 | 39 | public function getAppConfig() 40 | { 41 | return $this->server->getAppConfig(); 42 | } 43 | 44 | public function getAppName() 45 | { 46 | return $this->server->getAppName(); 47 | } 48 | 49 | public function getAppRunTimeEnv() 50 | { 51 | return $this->server->getAppRunTimeEnv(); 52 | } 53 | 54 | public function onStart($server, $workerId) 55 | { 56 | $this->swoole_server = $server; 57 | 58 | //监控app重加载时间 59 | $this->server->getAppMonitor()->onAppReload(); 60 | 61 | //当worker_id为0时添加定时器,驱动app监控信息上报 62 | // if($workerId == 0) 63 | // { 64 | // $this->swoole_server->addtimer(FSOFConstants::FSOF_MONITOR_TIMER); //5分钟监控一次数据5*60*1000 65 | // } 66 | 67 | \Logger::getLogger(__CLASS__)->debug("protocol onStart():{$workerId}"); 68 | } 69 | 70 | public function onConnect($server, $fd, $fromId) 71 | { 72 | 73 | } 74 | 75 | public function onReceive($server,$clientId, $fromId, $data, $reqInfo = null) 76 | { 77 | 78 | } 79 | 80 | public function onClose($server, $fd, $fromId) 81 | { 82 | 83 | } 84 | 85 | public function onShutdown($serv, $workerId) 86 | { 87 | 88 | } 89 | 90 | public function onTask($serv, $taskId, $fromId, $data) 91 | { 92 | 93 | } 94 | 95 | public function onFinish($serv, $taskId, $data) 96 | { 97 | 98 | } 99 | 100 | public function onTimer($serv, $interval) 101 | { 102 | switch( $interval ) 103 | { 104 | case FSOFConstants::FSOF_MONITOR_TIMER: 105 | { 106 | $this->server->getAppMonitor()->uploadMonitorData(); 107 | break; 108 | } 109 | } 110 | } 111 | 112 | public function onRequest($request, $response) 113 | { 114 | 115 | } 116 | } -------------------------------------------------------------------------------- /provider/core/protocol/BufferedProtocol.php: -------------------------------------------------------------------------------- 1 | checkBuffer($clientId, $data); 33 | \Logger::getLogger(__CLASS__)->debug("ret = ${ret}"); 34 | 35 | switch($ret) 36 | { 37 | case self::STATUS_ERROR: 38 | unset($this->requests[$clientId]); 39 | return true; // 错误的请求 40 | case self::STATUS_WAIT: 41 | return true; //数据不完整,继续等待 42 | default: 43 | break; // 完整数据 44 | } 45 | 46 | $request = $this->requests[$clientId]; 47 | if (!empty($reqInfo)) 48 | { 49 | $request->reqInfo = $reqInfo; 50 | } 51 | $this->server->setRequest($request); 52 | $this->onOneRequest($clientId, $request); 53 | unset($this->requests[$clientId]); 54 | } 55 | 56 | abstract public function checkBuffer($client_id, $data); 57 | 58 | abstract public function onOneRequest($client_id, $request); 59 | 60 | public function onClose($server, $fd, $fromId) 61 | { 62 | unset($this->requests[$fd]); 63 | } 64 | } -------------------------------------------------------------------------------- /provider/core/protocol/IProtocol.php: -------------------------------------------------------------------------------- 1 | sockType = SWOOLE_SOCK_TCP; 25 | 26 | $setting = array( 27 | 'open_tcp_nodelay' => 1, 28 | ); 29 | 30 | $this->setting = array_merge($this->setting, $setting); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /provider/monitor/AppMonitor.php: -------------------------------------------------------------------------------- 1 | appName = $appName; 46 | $this->appConfig = $appConfig; 47 | $this->curEnv = $appConfig['fsof_setting']['environment']; 48 | 49 | $this->serviceMonitor = new ServiceMonitor($this->appName, $this->appConfig); 50 | 51 | $this->appMonitorTable = new \swoole_table(8); 52 | $this->appMonitorTable->column(self::APP_START_TIME, \swoole_table::TYPE_STRING, 32); 53 | $this->appMonitorTable->column(self::APP_RELOAD_TIME, \swoole_table::TYPE_STRING, 32); 54 | $this->appMonitorTable->column(self::CUR_HANDLE_NUM, \swoole_table::TYPE_INT, 8); 55 | $this->appMonitorTable->create(); 56 | 57 | $this->reset(); 58 | } 59 | 60 | public function setServer($swooleServer) 61 | { 62 | $this->serviceMonitor->setServer($swooleServer); 63 | $this->swooleServer = $swooleServer; 64 | } 65 | 66 | public function reset() 67 | { 68 | $this->appMonitorTable->set($this->appName, array(self::CUR_HANDLE_NUM => 0)); 69 | } 70 | 71 | public function uploadMonitorData() 72 | { 73 | $data = $this->appMonitorTable->get($this->appName); 74 | $stats = $this->swooleServer->stats(); 75 | 76 | // 增加当前排队的任务数,更改当前连接的数目,今天连接的总数更新为服务启动以前连接的总数 77 | $msg = sprintf("%s|%s|%s|%d|%s|%s|%d|%d|%d", 78 | date('Y-m-d H:i:s'), 79 | $this->appName, 80 | $this->curEnv, 81 | $this->appConfig['server']['listen'][0], 82 | $data[self::APP_START_TIME], 83 | $data[self::APP_RELOAD_TIME], 84 | $stats['connection_num'], 85 | $data[self::CUR_HANDLE_NUM], 86 | $stats['tasking_num']); 87 | \Logger::getLogger(__CLASS__)->info($msg); 88 | 89 | $this->reset(); 90 | 91 | $this->serviceMonitor->uploadMonitorData(); 92 | } 93 | 94 | public function onAppStart() 95 | { 96 | $startTime = date('Y-m-d H:i:s'); 97 | $this->appMonitorTable->set($this->appName, array(self::APP_START_TIME => $startTime)); 98 | } 99 | 100 | public function onAppReload() 101 | { 102 | $reloadTime = date('Y-m-d H:i:s'); 103 | $this->appMonitorTable->set($this->appName, array(self::APP_RELOAD_TIME => $reloadTime)); 104 | } 105 | 106 | public function onRequest(DubboRequest $request) 107 | { 108 | $this->appMonitorTable->incr($this->appName,self::CUR_HANDLE_NUM); 109 | $this->serviceMonitor->onRequest($request); 110 | } 111 | 112 | public function onResponse(DubboRequest $request) 113 | { 114 | $this->appMonitorTable->decr($this->appName,self::CUR_HANDLE_NUM); 115 | $this->serviceMonitor->onResponse($request); 116 | } 117 | 118 | public function onError(DubboRequest $request) 119 | { 120 | $this->appMonitorTable->decr($this->appName,self::CUR_HANDLE_NUM); 121 | $this->serviceMonitor->onResponse($request); 122 | $this->serviceMonitor->onError($request); 123 | } 124 | } -------------------------------------------------------------------------------- /provider/monitor/OverloadMonitor.php: -------------------------------------------------------------------------------- 1 | appName = $appName; 34 | $this->overloadMonitorTable = new \swoole_table(2048); 35 | $this->overloadMonitorTable->column(self::CUR_OVERLOAD_NUM, \swoole_table::TYPE_INT, 8); 36 | $this->overloadMonitorTable->column(self::CUR_MUST_LOSS_NUM, \swoole_table::TYPE_INT, 8); 37 | $this->overloadMonitorTable->create(); 38 | $this->clear(); 39 | } 40 | 41 | public function __destruct() 42 | { 43 | if(!empty($this->overloadMonitorTable)) 44 | { 45 | $this->overloadMonitorTable->del($this->appName); 46 | unset($this->overloadMonitorTable); 47 | } 48 | } 49 | 50 | public function clear() 51 | { 52 | $this->overloadMonitorTable->set($this->appName, array(self::CUR_OVERLOAD_NUM => 0, self::CUR_MUST_LOSS_NUM => 0)); 53 | } 54 | 55 | public function resetOverloadNum_setLossNum($lossNum) 56 | { 57 | $this->overloadMonitorTable->set($this->appName, array(self::CUR_OVERLOAD_NUM => 0, self::CUR_MUST_LOSS_NUM => $lossNum)); 58 | } 59 | 60 | public function getLossNum() 61 | { 62 | $ret = 0; 63 | $data = $this->overloadMonitorTable->get($this->appName); 64 | if($data) 65 | { 66 | $ret = $data[self::CUR_MUST_LOSS_NUM]; 67 | } 68 | return $ret; 69 | } 70 | 71 | public function getoverloadNum() 72 | { 73 | $ret = 0; 74 | $data = $this->overloadMonitorTable->get($this->appName); 75 | if($data) 76 | { 77 | $ret = $data[self::CUR_OVERLOAD_NUM]; 78 | } 79 | return $ret; 80 | } 81 | 82 | public function overloadIncr() 83 | { 84 | $this->overloadMonitorTable->incr($this->appName, self::CUR_OVERLOAD_NUM); 85 | } 86 | 87 | public function lossNumDecr() 88 | { 89 | $this->overloadMonitorTable->decr($this->appName, self::CUR_MUST_LOSS_NUM); 90 | } 91 | } -------------------------------------------------------------------------------- /provider/monitor/ServiceMonitor.php: -------------------------------------------------------------------------------- 1 | appName = $appName; 54 | $this->appConfig = $appConfig; 55 | if(isset($appConfig['fsof_setting']['environment'])) 56 | { 57 | $this->curEnv = $appConfig['fsof_setting']['environment']; 58 | } 59 | 60 | $this->ServiceMonitorTable = new \swoole_table(1024); 61 | $this->ServiceMonitorTable->column(self::SERVICE_NAME, \swoole_table::TYPE_STRING, self::SWOOLE_TABLE_STRING); 62 | $this->ServiceMonitorTable->column(self::SERVICE_VERSION, \swoole_table::TYPE_STRING, self::SWOOLE_TABLE_VERSION); 63 | $this->ServiceMonitorTable->column(self::SERVICE_GROUP, \swoole_table::TYPE_STRING, self::SWOOLE_TABLE_STRING); 64 | $this->ServiceMonitorTable->column(self::SERVICE_SET, \swoole_table::TYPE_STRING, self::SWOOLE_TABLE_STRING); 65 | $this->ServiceMonitorTable->column(self::SERVICE_METHOD, \swoole_table::TYPE_STRING, self::SWOOLE_TABLE_STRING); 66 | $this->ServiceMonitorTable->column(self::AVR_HANDLE_NUM, \swoole_table::TYPE_INT, self::SWOOLE_TABLE_INT); 67 | $this->ServiceMonitorTable->column(self::AVR_ERROR_NUM, \swoole_table::TYPE_INT, self::SWOOLE_TABLE_INT); 68 | $this->ServiceMonitorTable->column(self::AVR_COST_TIME, \swoole_table::TYPE_INT, self::SWOOLE_TABLE_INT); 69 | $this->ServiceMonitorTable->column(self::FASTEST_COST_TIME, \swoole_table::TYPE_INT, self::SWOOLE_TABLE_INT); 70 | $this->ServiceMonitorTable->column(self::SLOWEST_COST_TIME, \swoole_table::TYPE_INT, self::SWOOLE_TABLE_INT); 71 | $this->ServiceMonitorTable->create(); 72 | 73 | $this->reset(); 74 | } 75 | 76 | public function setServer($swooleServer) 77 | { 78 | $this->swooleServer = $swooleServer; 79 | } 80 | 81 | public function reset() 82 | { 83 | foreach($this->ServiceMonitorTable as $row) 84 | { 85 | $key = $this->generateRowKey($row); 86 | $this->ServiceMonitorTable->set($key,array(self::AVR_HANDLE_NUM=>0,self::AVR_ERROR_NUM=>0,self::AVR_COST_TIME=>0,self::FASTEST_COST_TIME=>0,self::SLOWEST_COST_TIME=>0)); 87 | } 88 | } 89 | 90 | public function uploadMonitorData() 91 | { 92 | foreach($this->ServiceMonitorTable as $row) 93 | { 94 | $avrCost = $row[self::AVR_COST_TIME]; 95 | $avrHandleNum = $row[self::AVR_HANDLE_NUM]; 96 | if($avrHandleNum > 0) 97 | { 98 | $avrCost = $avrCost/$avrHandleNum; 99 | } 100 | else 101 | { 102 | $avrCost = 0; 103 | } 104 | 105 | $msg = sprintf("%s|%s|%s|%s|%s|%s|%d|%s|%d|%d|%d|%d|%d|%s", 106 | date('Y-m-d H:i:s'), 107 | $this->appName, 108 | $row[self::SERVICE_NAME], 109 | $row[self::SERVICE_VERSION], 110 | $row[self::SERVICE_GROUP], 111 | $this->curEnv, 112 | $this->appConfig['server']['listen'][0], 113 | $row[self::SERVICE_METHOD], 114 | $row[self::AVR_HANDLE_NUM], 115 | $row[self::AVR_ERROR_NUM], 116 | $avrCost, 117 | $row[self::SLOWEST_COST_TIME], 118 | $row[self::FASTEST_COST_TIME], 119 | $row[self::SERVICE_SET]); 120 | \Logger::getLogger(__CLASS__)->info($msg); 121 | } 122 | 123 | $this->reset(); 124 | } 125 | 126 | public function onRequest(DubboRequest $request) 127 | { 128 | $serviceLen = strlen($request->getService()); 129 | $versionLen = strlen($request->getVersion()); 130 | $groupLen = strlen($request->getGroup()); 131 | $methodLen = strlen($request->getMethod()); 132 | if($serviceLen>self::SWOOLE_TABLE_STRING || $versionLen>self::SWOOLE_TABLE_VERSION || $groupLen>self::SWOOLE_TABLE_STRING 133 | || $methodLen>self::SWOOLE_TABLE_STRING ) 134 | { 135 | \Logger::getLogger(__CLASS__)->error("Set swoole_table failed, More than the length of the table:".$request->getService(). 136 | " len:".$serviceLen."|".$request->getVersion()." len:".$versionLen."|".$request->getGroup()." len:".$groupLen."|".$request->getMethod(). 137 | " len:".$methodLen); 138 | return ; 139 | } 140 | 141 | $key = $this->generateRequestKey($request); 142 | if(!$this->ServiceMonitorTable->exist($key)) 143 | { 144 | $this->ServiceMonitorTable->set($key, array(self::SERVICE_NAME => $request->getService(), 145 | self::SERVICE_VERSION => $request->getVersion(), 146 | self::SERVICE_GROUP => $request->getGroup(), 147 | self::SERVICE_METHOD => $request->getMethod())); 148 | } 149 | } 150 | 151 | public function onResponse(DubboRequest $request) 152 | { 153 | $key = $this->generateRequestKey($request); 154 | $data = $this->ServiceMonitorTable->get($key); 155 | if($data) 156 | { 157 | //当前这次请求耗时 158 | $thisCost = (int)(($request->endTime - $request->startTime)*1000000); 159 | 160 | //最快耗时 161 | if (0 == $data[self::FASTEST_COST_TIME]) 162 | { 163 | $data[self::FASTEST_COST_TIME] = $thisCost; 164 | } 165 | else if($data[self::FASTEST_COST_TIME] > $thisCost) 166 | { 167 | $data[self::FASTEST_COST_TIME] = $thisCost; 168 | } 169 | 170 | //最慢耗时 171 | if($data[self::SLOWEST_COST_TIME] < $thisCost) 172 | { 173 | $data[self::SLOWEST_COST_TIME] = $thisCost; 174 | } 175 | 176 | //平均耗时 = $data[self::AVR_COST_TIME]/$data[self::AVR_HANDLE_NUM] 177 | $avrCost = $data[self::AVR_COST_TIME]; 178 | $data[self::AVR_COST_TIME] = $avrCost + $thisCost; 179 | $this->ServiceMonitorTable->set($key, array(self::AVR_COST_TIME => $data[self::AVR_COST_TIME], 180 | self::FASTEST_COST_TIME => $data[self::FASTEST_COST_TIME], 181 | self::SLOWEST_COST_TIME => $data[self::SLOWEST_COST_TIME])); 182 | 183 | $this->ServiceMonitorTable->incr($key,self::AVR_HANDLE_NUM); 184 | } 185 | } 186 | 187 | public function onError(DubboRequest $request) 188 | { 189 | $key = $this->generateRequestKey($request); 190 | if($this->ServiceMonitorTable->exist($key)) 191 | { 192 | $this->ServiceMonitorTable->incr($key,self::AVR_ERROR_NUM); 193 | } 194 | } 195 | 196 | private function generateRowKey($row) 197 | { 198 | $key = $row[self::SERVICE_NAME].':'.$row[self::SERVICE_VERSION].':'.$row[self::SERVICE_GROUP].':'.$row[self::SERVICE_METHOD]; 199 | return $key; 200 | } 201 | 202 | private function generateRequestKey($req) 203 | { 204 | $key = $req->getService().':'.$req->getVersion().':'.$req->getGroup().':'.$req->getMethod(); 205 | return $key; 206 | } 207 | } -------------------------------------------------------------------------------- /provider/shell/StartUp.php: -------------------------------------------------------------------------------- 1 | info("input {$cmd} {$name}"); 65 | $server = new TcpServer($name); 66 | //加载app root目录下的bootstrap.php和provider/$name.provider文件 67 | $server->setRequire(FSOFConfigManager::getProviderAppRoot($name)); 68 | 69 | //app/conf目录下的$name.deploy文件 70 | $server->loadConfig($config); 71 | //全局fsof.ini文件 72 | $server->loadConfig(FSOFConfigManager::getFSOFIni()); 73 | 74 | //设置swoole扩展日志文件 75 | $server->setSwooleLogFile($cmd); 76 | 77 | //provider启动时初始化consumer 78 | $server->initConsumer(); 79 | 80 | //初始化server资源 81 | $server->initRunTime('/var/fsof/provider'); 82 | 83 | //启动 84 | $server->run($cmd); -------------------------------------------------------------------------------- /registry/BootStrap.php: -------------------------------------------------------------------------------- 1 | $frameRootPathDepth) 37 | { 38 | $key = $className = $class; 39 | if($pathDepth > $frameRootPathDepth + 1) 40 | { 41 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 2); 42 | $className = $root[$frameRootPathDepth + 1]; 43 | unset($root[$frameRootPathDepth + 1]); 44 | $key = implode($root, '\\'); 45 | } 46 | else if($pathDepth == $frameRootPathDepth + 1) 47 | { 48 | $root = explode('\\', trim($class, '\\'), $frameRootPathDepth + 1); 49 | $className = $root[$frameRootPathDepth]; 50 | unset($root[$frameRootPathDepth]); 51 | $key = implode($root, '\\'); 52 | } 53 | 54 | if(isset(self::$nsPath[$key])) 55 | { 56 | include_once self::$nsPath[$key] . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php'; 57 | } 58 | } 59 | } 60 | 61 | /** 62 | * 设置根命名空间 63 | * @param $root 64 | * @param $path 65 | */ 66 | public static function setRootNS($root, $path) 67 | { 68 | self::$nsPath[$root] = $path; 69 | } 70 | } -------------------------------------------------------------------------------- /registry/automatic/ConsumerProxy.php: -------------------------------------------------------------------------------- 1 | logger = \Logger::getLogger(__CLASS__); 42 | $this->config = $config; 43 | } 44 | 45 | /** 46 | * consumer根据查找条件组合,获取相应provider URL信息。ConsumerProxy内部实现共享内存和文件缓存两级缓存,先读共享内存,找不到再度文件缓存 47 | */ 48 | public function getProviders($service, $version=FSOFConstants::FSOF_SERVICE_VERSION_DEFAULT, $group=FSOFConstants::FSOF_SERVICE_GROUP_ANY) 49 | { 50 | try 51 | { 52 | //获取路由信息 53 | $providerInfo = FSOFRedis::instance($this->config)->getProviderInfo($service); 54 | return $this->filterProviderUrls($providerInfo, $version, $group, $service); 55 | } 56 | catch (\Exception $e) 57 | { 58 | //数据异常关闭连接 59 | FSOFRedis::instance()->close(); 60 | $this->logger->error('get Provider Info from redis exception:'.$e->getMessage(),$e); 61 | return NULL; 62 | } 63 | } 64 | 65 | private function filterProviderUrls($providerInfo, $version, $group, $service) 66 | { 67 | $urls = array(); 68 | if (is_array($providerInfo)) 69 | { 70 | foreach ($providerInfo as $index => $url) 71 | { 72 | try 73 | { 74 | $urlObj = new FSOFUrl($url); 75 | if (!empty($urlObj)) 76 | { 77 | //服务校验 78 | if (0 == strncmp($urlObj->getService(), $service, strlen($service))) 79 | { 80 | //服务Version强校验 81 | if ($version == $urlObj->getVersion(FSOFConstants::FSOF_SERVICE_VERSION_DEFAULT)) 82 | { 83 | if ($group == FSOFConstants::FSOF_SERVICE_GROUP_ANY || $group == $urlObj->getGroup(FSOFConstants::FSOF_SERVICE_GROUP_DEFAULT)) 84 | { 85 | $urls[] = $urlObj; 86 | if($this->logger->isDebugEnabled()){ 87 | $this->logger->debug("find provider form redis for [$service:$version:$group],url:".json_encode($url,true)); 88 | } 89 | } 90 | } 91 | } 92 | else 93 | { 94 | //数据出现乱序关闭连接 95 | FSOFRedis::instance()->close(); 96 | $this->logger->error('get redis data exception, service:'.$service.'; redis data list:'.json_encode($providerInfo,true)); 97 | break; 98 | } 99 | } 100 | } 101 | catch (\Exception $e) 102 | { 103 | $this->logger->error('error of url:' . $url, $e); 104 | } 105 | } 106 | } 107 | if (empty($urls)) 108 | { 109 | $this->logger->warn('version:' .$version. ' group:' .$group. ' service:' .$service. ' get Provider Info from redis is empty.'); 110 | } 111 | return $urls; 112 | } 113 | } 114 | 115 | -------------------------------------------------------------------------------- /registry/automatic/RegistryService.php: -------------------------------------------------------------------------------- 1 | logger = \Logger::getLogger(__CLASS__); 29 | $zkHostStr = ''; 30 | foreach($registryUrl as $fsofUrl) 31 | { 32 | $zkHostStr .= $fsofUrl->getHost().':'.$fsofUrl->getPort().','; 33 | } 34 | $this->zookeeperAddr = rtrim($zkHostStr,',');//去掉最后的, 35 | 36 | try 37 | { 38 | $this->zookeeperClient = new ZookeeperClient(); 39 | } 40 | catch (\Exception $e) 41 | { 42 | throw new \Exception("连接zookeeper失败".$e->getMessage()); 43 | } 44 | } 45 | 46 | public function __destruct() 47 | { 48 | unset($this->zookeeperClient); 49 | } 50 | 51 | public function connectZk($ephemeral) 52 | { 53 | return $this->zookeeperClient->connectZk($this->zookeeperAddr, $ephemeral); 54 | } 55 | 56 | public function register($url) 57 | { 58 | $ret = false; 59 | 60 | $this->logger->info('registryService::register|url:'.$url->getOriginUrl().'|path:'.$url->getZookeeperPath()); 61 | try 62 | { 63 | $ret = $this->zookeeperClient->create($url->getZookeeperPath()); 64 | } 65 | catch (\Exception $e) 66 | { 67 | $ret = false; 68 | throw new \Exception("注册service到zookeeper失败".$e->getMessage()); 69 | } 70 | 71 | return $ret; 72 | } 73 | 74 | public function unregister($url) 75 | { 76 | $path = $url->getZookeeperPath(); 77 | return $this->zookeeperClient->delete($path); 78 | } 79 | 80 | public function subscribe($url, $listener) 81 | { 82 | } 83 | 84 | 85 | public function unsubscribe($url, $listener) 86 | { 87 | } 88 | 89 | 90 | public function lookup($url) 91 | { 92 | } 93 | 94 | public function registerCallFunc($func) 95 | { 96 | $this->zookeeperClient->registerCallFunc($func); 97 | } 98 | 99 | public function setLogFile($file, $level = 2) 100 | { 101 | $this->zookeeperClient->setLogFile($file, $level); 102 | } 103 | } -------------------------------------------------------------------------------- /registry/automatic/RegistryServiceFactory.php: -------------------------------------------------------------------------------- 1 |