├── .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 | 
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 |